Nginx 监控全链路:从零接入 Prometheus + Grafana 一、为什么需要单独监控 NginxNginx 跑着跑着连接数飙了、请求延迟涨了等发现的时候用户已经在骂了。Prometheus Grafana 能提前看到趋势而不是等告警响了才冲进去救火。但 Prometheus 不会直接扒 Nginx 的状态——中间需要一个翻译官把 Nginx 的内部指标转成 Prometheus 能懂的格式。这就是 nginx-prometheus-exporter。整个链路长这样Nginx stub_status → nginx-prometheus-exporter → Prometheus 采集 → Grafana 展示三步走开 stub_status → 部署 exporter → 接 Prometheus Grafana。二、开启 Nginx stub_statusstub_status 由ngx_http_stub_status_module模块提供官方源码默认不编译需在编译时加--with-http_stub_status_module。但主流 Linux 发行版CentOS/Ubuntu 的官方源、EPEL预编译的 Nginx 包通常已包含。1. stub_status 是干什么的开启后 Nginx 会暴露一个简单的状态页面只输出一行纯文本包含7 个实时指标Active connections: 291 server accepts handled requests 16630948 16630948 31070465 Reading: 6 Writing: 179 Waiting: 106指标含义用途Active connections当前活跃连接总数判断 Nginx 负载水位accepts累计接收的连接数配合 handled 看丢了多少连接accepts ≠ handled 说明连接被拒绝handled累计处理完成的连接数同上requests累计收到的请求数计算 QPS一个连接可能发多个请求Reading正在读请求头的连接数过高说明客户端发请求慢或有攻击Writing正在写响应的连接数过高说明后端处理慢Nginx 在等WaitingKeep-Alive 空闲连接数正常水位太高可调keepalive_requests为什么需要它Prometheus 不会直接读 Nginx 内部状态stub_status 就是 Nginx 向外暴露指标的窗口。后面部署的nginx-prometheus-exporter会定期访问这个页面把文本指标转成 Prometheus 能懂的格式再由 Grafana 画图——没有这扇窗口整个监控链路的起点就没有了。2. 检查模块是否已编译nginx-V21|grep-owith-http_stub_status_module有输出说明已编译进去直接改配置即可。如果没输出需要重新编译 Nginx 并加上--with-http_stub_status_module。3. 配置 stub_status确认模块存在后在 nginx.conf 加一个 locationserver { listen 127.0.0.1:18081; server_name localhost; location /nginx_status { stub_status on; allow 127.0.0.1; deny all; } }4. 重载并验证重载 Nginxnginx-tnginx-sreload验证curlhttp://127.0.0.1:18081/nginx_status输出示例如果看到这个说明 stub_status 已成功开启。注意只开了 127.0.0.1 白名单exporter 要部署在同一台机器上才能读到。三、部署 nginx-prometheus-exporter1. 下载 exporter# 最新版 v1.5.1wgethttps://github.com/nginx/nginx-prometheus-exporter/releases/download/v1.5.1/nginx-prometheus-exporter_1.5.1_linux_arm64.tar.gztarxzf nginx-prometheus-exporter_1.5.1_linux_arm64.tar.gzmvnginx-prometheus-exporter /usr/local/bin/2. 创建 systemd 服务cat/etc/systemd/system/nginx-prometheus-exporter.serviceEOF [Unit] DescriptionNginx Prometheus Exporter Afternetwork.target [Service] Typesimple Userroot ExecStart/usr/local/bin/nginx-prometheus-exporter \ -nginx.scrape-urihttp://127.0.0.1:18081/nginx_status Restartalways [Install] WantedBymulti-user.target EOF3. 启动并验证systemctl daemon-reload systemctlenablenginx-prometheus-exporter--nowsystemctl status nginx-prometheus-exporter验证指标输出curl-shttp://localhost:9113/metrics|head-20看到类似输出说明 exporter 正常工作四、接入 Prometheus1. 添加 scrape 配置在 Prometheus 配置文件的scrape_configs下新增一个 job一般在/etc/prometheus/prometheus.yml-job_name:nginxstatic_configs:-targets:-172.16.130.2:9113labels:instance:nginx-prod-01-targets:-172.16.130.58:9113labels:instance:nginx-prod-02参数说明字段值说明targetsIP:9113exporter 默认监听 9113 端口scrape_interval省略用 Prometheus 全局默认一般 15slabels.instance自定义Grafana 里用来区分不同 Nginx 实例2. 加载 Prometheus#systemd 重启systemctl restart prometheus3. 验证采集状态打开 Prometheus Web UIhttp://IP:9090/targets确认nginxjob 的 State 为UP。或者直接查指标# Prometheus 表达式输入框 nginx_connections_active有数据返回就说明采集正常。五、Grafana 可视化1. 下载官方 Dashboard内网环境内网 Grafana 无法直接从 grafana.com 在线导入需要先下载 JSON 文件**grafana官网**https://grafana.com/api/dashboards/17452/revisions/1/download官方 GitHubhttps://raw.githubusercontent.com/nginxinc/nginx-prometheus-exporter/main/grafana/dashboard.json把 JSON 文件传到能访问内网 Grafana 的机器上然后导入。2. 导入步骤Grafana 左侧菜单 →Dashboards→New→Import点击Upload JSON file选择下载的dashboard.json在 Prometheus 下拉框选择配置的数据源 → 点击Import3. 面板概览官方 Dashboard 包含以下核心面板面板指标说明NGINX Statusnginx_up绿正常红挂了Processed connectionsnginx_connections_accepted/handled连接处理速率曲线Active Connectionsreading/writing/waiting/active四类连接实时分拆Total requestsnginx_http_requests_total请求 QPS 折线图3. 告警规则# prometheus rulesgroups:-name:nginxrules:# 存活告警 -alert:NginxDownexpr:nginx_up{jobnginx} 0for:1mlabels:severity:criticalannotations:summary:Nginx 不可达description:{{ $labels.instance }} 的 nginx 进程可能已停止请立即检查-alert:NginxExporterDownexpr:up{jobnginx} 0for:1mlabels:severity:criticalannotations:summary:Nginx Exporter 已停止description:{{ $labels.instance }} 的 exporter 进程挂了nginx 状态未知# 连接数告警 -alert:NginxHighConnectionsexpr:nginx_connections_active{jobnginx}10000for:2mlabels:severity:warningannotations:summary:Nginx 活跃连接数过高description:{{ $labels.instance }} 当前活跃连接 {{ $value }}超过 10000 阈值# 错误率告警 -alert:NginxRequestRateHighexpr:rate(nginx_http_requests_total{jobnginx}[5m])5000for:5mlabels:severity:warningannotations:summary:Nginx QPS 异常升高description:{{ $labels.instance }} 当前 QPS {{ $value }}请确认是否有流量冲击告警说明规则表达式含义NginxDownnginx_up 0exporter 正常但连不上 nginx进程挂了或端口不通NginxExporterDownup 0exporter 自身已停止nginx 状态未知NginxHighConnectionsnginx_connections_active 10000活跃连接超阈值可能后端处理慢NginxRequestRateHighrate(nginx_http_requests_total[5m]) 5000QPS 异常飙升需确认是否受攻击关键区分nginx_up是 exporter 上报的能区分 nginx 挂了 vs exporter 挂了up是 Prometheus 自己加的scrape 是否成功。挂了up{jobnginx} 0只能说明 scrape 失败分不清是 exporter 崩了还是 nginx 崩了所以两条都要配。六、关键指标速查指标名类型含义告警参考nginx_connections_activeGauge当前活跃连接数 10000nginx_connections_readingGauge正在读请求头的连接持续增长说明请求慢nginx_connections_writingGauge正在写响应的连接过高说明后端慢nginx_connections_waitingGaugeKeep-Alive 空闲连接结合 readingwriting 看吞吐nginx_http_requests_totalCounter累计请求数按状态码分用rate()算 QPSnginx_upGaugeexporter 能否连上 Nginx 0 时告警最常用的 PromQL# QPS rate(nginx_http_requests_total[1m]) # 5xx 错误率 rate(nginx_http_requests_total{status~5..}[5m]) / rate(nginx_http_requests_total[5m]) # 连接数趋势 nginx_connections_active七、总结整个部署链路一句话Nginx 开 stub_status → 装 exporter → Prometheus 加 job → Grafana 导面板。落地清单nginx.conf 中启用stub_status限制 127.0.0.1 访问部署 nginx-prometheus-exporter v1.5.1systemd 管理curl localhost:9113/metrics验证 exporter 输出正常Prometheusscrape_configs添加nginxjobPrometheus Targets 确认 State UPGrafana 导入 Dashboard 17452加上 5xx 错误率 高连接数告警注意exporter 不挑 Nginx 版本1.18 ~ 1.30 全兼容只要 stub_status 开着就行。