Nginx 监控运维怎么做?stub_status、Prometheus、ELK 怎么选?
答案前置:Nginx 监控运维的核心思路
Nginx 监控围绕三条线展开:指标采集(stub_status / 日志)→ 存储与展示(Prometheus+Grafana / ELK / Zabbix)→ 告警与响应(阈值告警 + 自动化脚本)。面试中常考的不是你背了多少工具名,而是能不能说清楚每一步为什么这么做、不同规模场景怎么选型。
内置指标:stub_status 能拿到什么?
stub_status 是 Nginx 自带的状态模块,开启后在指定路径暴露一组关键指标:
nginxlocation /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }
访问后返回:Active connections(当前活跃连接数)、accepts/handled/requests(累计连接与请求数)、Reading/Writing/Waiting(读请求头、写响应、空闲等待的连接数)。
追问:Waiting 数量大说明什么? 如果 Active connections ≈ Waiting,说明大量连接是 keep-alive 空闲态,连接复用率高是好事;但如果同时 Writing 偏低而请求排队,就要检查上游响应是否过慢。
日志监控:比 stub_status 更细的粒度
stub_status 只有粗粒度指标,真正定位问题靠日志。关键是自定义 log_format 加入上游响应时间:
nginxlog_format detailed '$remote_addr - [$time_local] "$request" $status ' 'rt=$request_time uct=$upstream_connect_time ' 'uht=$upstream_header_time urt=$upstream_response_time'; access_log /var/log/nginx/detailed.log detailed;
request_time 是总耗时,upstream_response_time 是上游处理耗时,两者差值就是 Nginx 自身开销。如果差值大,排查 Nginx 层面的缓冲、压缩或 DNS 解析。
对于 ELK 场景,直接输出 JSON 格式日志省掉 Logstash 的 grok 解析:
nginxlog_format json_log escape=json '{"time":"$time_local","ip":"$remote_addr",' '"status":$status,"rt":$request_time,"urt":"$upstream_response_time"}'; access_log /var/log/nginx/json.log json_log;
Prometheus + Grafana:云原生场景首选
nginx-prometheus-exporter 把 stub_status 的指标转为 Prometheus 格式,Grafana 做可视化:
yaml# prometheus.yml scrape_configs: - job_name: 'nginx' static_configs: - targets: ['localhost:9113']
选型逻辑: 容器化/K8s 环境下 Prometheus 是事实标准,开箱即用 Service Discovery,Grafana 社区模板丰富。Nginx Plus 用户还可以用官方 nginx-plus-exporter 拿到更细的 upstream 指标。
ELK Stack:日志深度分析场景
当需求不只是看指标曲线,而是要按 IP、URL、状态码做聚合分析和历史追溯,ELK 更合适。Filebeat 采集 → Logstash 清洗 → Elasticsearch 存储 → Kibana 可视化,链路长但灵活度高。
选型对比: Prometheus 适合指标型监控(数字曲线),ELK 适合日志型分析(文本检索+聚合)。小团队二选一推荐 Prometheus,监控告警闭环更短。
Zabbix:传统企业环境的选择
Zabbix 通过 Agent 调用 stub_status 页面,用正则提取指标配置监控项。适合已有 Zabbix 基建的企业,不推荐新项目为 Nginx 单独搭 Zabbix。
告警:监控闭环的关键
有监控没告警等于没监控。核心告警规则:
- 5xx 比率超阈值(如 > 1%)触发 critical
- Active connections 突增超过 2 倍标准差触发 warning
- upstream_response_time P99 > 2s 触发 warning
Prometheus 用 Alertmanager 配路由和静默,ELK 用 Watcher 或 ElastAlert,Zabbix 自带触发器机制。
运维常用命令速查
bashnginx -t # 测试配置语法 nginx -s reload # 平滑重载,不中断连接 nginx -s quit # 优雅停止,处理完当前请求后退出 nginx -s reopen # 重新打开日志文件(配合 logrotate)
日志轮转用 logrotate,配置 postrotate 里发 USR1 信号让 Nginx 重新打开文件句柄,避免写入已轮转的老文件。
面试追问方向
- stub_status 的 Waiting 和 keep-alive 是什么关系? Waiting 连接就是 keep-alive 空闲连接,
keepalive_timeout控制超时回收。 - Nginx 502 怎么排查? 先查 upstream 是否存活,再看 Nginx error log 里
connect() failed的具体原因,最后检查proxy_read_timeout配置。 - 如何不重启更新配置?
nginx -t && nginx -s reload,reload 会 fork 新 worker 加载新配置,老 worker 处理完手头请求后退出。 - Prometheus 和 ELK 怎么选? 指标监控选 Prometheus(轻量、告警闭环好),日志分析选 ELK(全文检索、聚合灵活),大团队通常两套都搭。