核心是让$upstream_status稳定落盘、可分离、能聚合,并与后端地址和时间强绑定,再通过轻量实时分析触发分级响应;需定义含$upstream_status、$upstream_addr、$time_iso8601或$msec、$upstream_response_time的日志格式,配合分钟级awk检测、实例级定位、快照采集及error.log交叉验证实现精准告警。

核心是让 $upstream_status 稳定落盘、可分离、能聚合,并与后端地址和时间强绑定,再通过轻量实时分析触发分级响应。
定义含关键状态变量的专用日志格式
在 http 块中明确定义日志格式,必须包含以下字段:
-
$upstream_status:真实上游返回码,502/503/504 等均由此体现;值为“-”表示未转发,采集时需过滤 -
$upstream_addr:实际通信的后端地址(如10.0.1.22:8080或unix:/tmp/backend.sock),用于故障归因 -
$time_iso8601或$msec:高精度时间戳,支撑秒级窗口统计 -
$upstream_response_time:辅助判断是否为性能型 5xx(如 504 常伴随高耗时)
示例配置:
log_format upstream_alert '$time_iso8601|$remote_addr|$request_method|$uri|$status|$upstream_status|$upstream_addr|$upstream_response_time|$request_time';access_log /var/log/nginx/upstream-alert.log upstream_alert buffer=32k flush=1s;
用轻量脚本实现分钟级状态码波动检测
避免依赖重型采集链路,可用每分钟执行一次的 shell + awk 组合快速识别异常:
- 提取最近 60 秒日志中所有非“-”的
$upstream_status,按 5xx/非 5xx 分组计数 - 计算 5xx 占比:若前 1 分钟 > 3% 且较前 5 分钟均值上升超 3 倍,触发一级告警
- 对 502/503/504 单独计数:502 突增往往指向进程崩溃,503 集中出现提示上游限流器生效,504 则需检查
proxy_read_timeout与后端处理能力是否匹配
基于 upstream_addr 实现实例级定位与自动快照
5xx 不是抽象指标,必须落到具体后端节点:
- 用
awk '{print $6,$7}' /var/log/nginx/upstream-alert.log | sort | uniq -c | sort -nr | head -5快速找出高频出错的upstream_addr - 告警时同步执行快照:curl http://localhost/status(需启用 stub_status)、抓取该地址最近 200 行 access 日志、输出当前 upstream 健康检查状态(
nginx -T 2>/dev/null | grep -A 10 "upstream.*backend") - 若使用服务发现(如 Consul),可在告警内容中注入服务名、集群、机房等上下文,减少人工查证环节
与健康检查和 error.log 交叉验证防误报
单看 access 日志易受干扰,需叠加信号增强可信度:
- 检查
error.log是否同期出现upstream timed out(504 主因)、connect() failed (111)(502 常见于后端停服)、no live upstreams(全节点下线) - 确认该
upstream_addr是否被标记为temporarily disabled,判断是瞬时抖动还是持续熔断 - 若 5xx 上升同时
$upstream_response_time中位数翻倍,基本可排除网络层问题,聚焦后端应用自身瓶颈










