需通过 ngx_http_vts_module 采集各 server 的 5xx 与总请求数,用增量差值计算滚动窗口错误率,并借助 Prometheus/Alertmanager 或脚本+Webhook 实现告警;须为每个 server 独立配置 vhost_traffic_status on、避免 server_name 冲突、以 server_name 为 key 解析指标。

要基于 ngx_http_vts_module 构建针对不同虚拟主机(server)错误率的实时告警体系,核心在于:采集各 server 的 5xx 错误计数与总请求数,计算滚动窗口内的错误率,并通过外部工具触发告警。该模块本身不提供告警能力,需配合 Prometheus + Grafana + Alertmanager 或脚本轮询 + Webhook 实现。
1. 启用并配置 vts 模块按 server 维度暴露指标
ngx_http_vts_module 默认以 JSON 格式在 /status/format/json 提供聚合数据。要区分虚拟主机,必须确保每个 server 块启用 vhost_traffic_status on,且不共用同一 server_name 别名(否则统计合并):
- 在全局 http 块中加载模块并开启基础统计:
vhost_traffic_status_zone; - 在每个独立的
server块内显式开启:vhost_traffic_status on; - 避免多个 server 使用相同
server_name(如都写localhost),否则指标会归入同一 vhost 条目
2. 提取各虚拟主机的 5xx 错误率(需定时采集)
vts 的 JSON 输出中,每个 vhost 对应一个对象,其 responses.status.5xx 表示累计 5xx 总数,requests.total 表示总请求数。错误率需用滑动窗口计算(如最近 60 秒),不能直接用累计值——否则低流量站点误差极大。
- 推荐每 10 秒请求一次
/status/format/json,解析出各 vhost 的5xx和total - 本地缓存前一次采集值,用差值计算单位时间增量(例如:当前 5xx - 上次 5xx)
- 错误率 =
Δ5xx / Δtotal(若 Δtotal == 0,则跳过或设为 0) - 示例 Python 片段逻辑:
data = requests.get("http://nginx/status/format/json").json()
for vhost in data["servers"]["server"]:
name = vhost["server_name"]
curr_5xx = vhost["responses"]["status"]["5xx"]
curr_total = vhost["requests"]["total"]
# 计算增量并更新缓存
3. 接入监控与告警链路(两种轻量方案)
方案 A:Prometheus + 自定义 exporter
写一个简易 exporter(如 Python + Flask),定时抓取 vts JSON,将每个 vhost 的 vts_server_5xx_rate 作为 Gauge 暴露给 Prometheus。在 PromQL 中可直接写:rate(vts_server_5xx_total[1m]) / rate(vts_server_requests_total[1m]) > 0.05
然后在 Alertmanager 配置邮件、钉钉等通知。
方案 B:Shell 脚本 + cURL + Webhook
用 crontab 每 30 秒执行脚本,当某 vhost 错误率连续 3 次 > 3% 时,调用企业微信/飞书机器人 Webhook 发送告警,含 vhost 名、错误率、时间戳。
4. 注意事项与常见坑点
- vts 的
server数组顺序不固定,务必用server_name字段做 key 匹配,不要依赖索引 - 首次启动后需有真实流量才能产生非零统计,空载时所有值为 0,会导致除零错误
- 若使用 HTTPS server,
server_name必须与 SNI 域名一致,否则可能被归入 default server - 高并发下频繁请求
/status可能轻微影响 Nginx 性能,建议限制采集频率 ≤ 5s/次,并加 nginx 限流(limit_req)










