Nginx限流监控告警核心是:通过自定义日志格式记录limit_req_status、定时脚本解析日志统计拒绝次数并阈值告警,或用Prometheus+nginx-vts-exporter实现指标化监控。

在 Nginx 中监控限流触发次数并告警,核心思路是:利用 limit_req 模块的日志记录能力 + 自定义日志格式捕获被拒绝请求 + 定时脚本解析日志统计频次 + 达到阈值后触发告警(如发邮件、调用 Webhook)。
1. 配置 Nginx 记录限流拒绝事件
Nginx 默认不会单独标记被限流拒绝的请求(HTTP 503 或 429),需通过 log_format 和 limit_req_status 配合,让日志能区分“正常响应”和“限流拦截”。
在 http 块中添加:
log_format limit_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time" '
'limit_status=$limit_req_status';
<p>map $limit_req_status $limit_req_status_code {
503 1;
429 1;
default 0;
}</p>在 server 或 location 中启用限流并指定日志:
limit_req zone=api burst=10 nodelay; limit_req_status 429; # 统一返回 429,便于识别(可选,但推荐) access_log /var/log/nginx/limit_access.log limit_log;
✅ 关键点:
- $limit_req_status 变量仅在请求被限流拒绝时有值(默认 503,设为 429 后更明确);
- map 将其转为 1/0,方便后续用 awk/grep 快速过滤;
- 日志独立输出(如 limit_access.log),避免干扰主访问日志。
2. 编写定时监控脚本(Shell 示例)
以下脚本每分钟检查最近 60 秒内限流触发次数,超阈值(如 ≥50 次)则告警:
#!/bin/bash
LOG_FILE="/var/log/nginx/limit_access.log"
THRESHOLD=50
WINDOW_SEC=60
ALERT_FILE="/tmp/nginx_limit_alert.lock"
<h1>获取最近 WINDOW_SEC 秒内的限流行数(匹配 limit_status=429 或 =503)</h1><p>COUNT=$(awk -v cutoff="$(date -d '-'"${WINDOW_SEC}"' seconds' '+%d/%b/%Y:%H:%M:%S')" \
'$4 ~ /[.*]/ && substr($4,2,15) >= cutoff && $12 ~ /limit_status=(429|503)/ {c++} END{print c+0}' "$LOG_FILE")</p><p>if [ "$COUNT" -ge "$THRESHOLD" ]; then
if [ ! -f "$ALERT_FILE" ] || [ "$(find "$ALERT_FILE" -mmin -5)" ]; then</p><h1>防重复告警:5 分钟内只发一次</h1><pre class='brush:php;toolbar:false;'> echo "$(date): High limit_req rate: ${COUNT} in ${WINDOW_SEC}s" | logger -t nginx-limit-alert
# 发邮件示例
echo "Nginx limit triggered ${COUNT} times in ${WINDOW_SEC}s" | mail -s "[ALERT] Nginx Rate Limit Spike" admin@example.com
# 或调用企业微信/Webhook(略)
touch "$ALERT_FILE"
fielse rm -f "$ALERT_FILE" # 恢复后清除锁 fi
? 注意:
- 使用 awk 按时间戳精确截取窗口,比 tail -n 更可靠;
- 加锁机制防止高频误报;
- 日志路径、阈值、告警方式按需调整。
3. 替代方案:用 Prometheus + nginx-vts-exporter(适合长期运维)
若已有 Prometheus 生态,更推荐用指标化方式:
- 编译或安装 nginx-module-vts(支持限流 zone 实时计数);
- 配置 Nginx 开启 vhost_traffic_status_zone;
- 部署 nginx-vts-exporter 抓取指标,暴露
nginx_vts_limit_requests_dropped_total; - 在 Prometheus 中写告警规则:
sum(rate(nginx_vts_limit_requests_dropped_total[1m])) > 50
✅ 优势:实时、可聚合、带标签(按 zone、host 区分)、天然接入 Grafana 可视化。
4. 补充建议
-
日志轮转:确保
logrotate正确处理limit_access.log,并在 postrotate 中 reload nginx 或通知脚本重载文件句柄; -
权限注意:脚本运行用户(如
www-data)需有读日志权限; -
测试验证:用
ab或hey突发压测触发限流,确认日志出现limit_status=429并被脚本捕获; -
避免漏报:若使用
burst+nodelay,部分请求可能被延迟而非拒绝,此时应关注limit_req_status为 0 的“排队过长”行为(需自定义日志字段记录排队时间)。
不复杂但容易忽略的是日志时间精度和脚本执行时机——确保系统时间同步(NTP),且 cron 任务间隔 ≤ 监控窗口,才能及时发现问题。


















