Nginx 实时请求监测项目实践指南

在现代 Web 架构中,实时监控 Nginx 的请求状况对于性能优化、故障排查、安全防护至关重要。本文将提供一套完整的 Nginx 实时请求监测项目实践方案,涵盖数据采集、传输、存储、可视化、告警全流程,并提供可直接落地的代码示例和配置。

图片[1]_Nginx 实时请求监测项目实践指南_知途无界

一、监测核心指标与方案选型

1.1 关键监测指标

类别核心指标说明
连接状态Active connections, Reading, Writing, Waiting反映 Nginx 并发处理能力
请求吞吐Requests/sec, Total requestsQPS、TPS 性能基准
请求延迟Request time, Upstream response time评估服务响应性能
状态码分布2xx, 3xx, 4xx, 5xx counts判断业务逻辑正确性与错误率
上游服务Upstream health, Response time, Failures监控后端服务健康状态
流量带宽Bytes sent/received per sec网络资源使用情况

1.2 技术方案选型对比

方案原理优点缺点适用场景
Stub StatusNginx 内置模块,暴露基础状态页简单、零依赖、性能好指标少,无细分维度快速查看基础连接数/QPS
Access Log解析 Nginx 访问日志指标最全(IP、URL、UA、耗时等)需日志采集、解析开销大深度业务分析与审计
OpenTelemetry注入 tracing 链路,收集指标现代化、标准化、生态丰富需改造应用或 Nginx 插件微服务全链路观测
Commercial APMNew Relic, Datadog 等开箱即用、功能强大成本高、数据隐私风险企业级付费监控

推荐组合方案​:
Stub Status(实时监控) + Access Log(深度分析) + Prometheus/Grafana(可视化)​,兼顾实时性、深度与成本。


二、数据采集层实践

2.1 方案一:Nginx Stub Status 模块(必选)

步骤 1:启用 Stub Status 模块

确保 Nginx 编译时包含 --with-http_stub_status_module(通过 nginx -V 检查)。
nginx.confserver 块中添加:

server {
    listen 8080; # 专用于状态监控的端口,避免与主业务冲突
    location /nginx_status {
        stub_status on;
        access_log off; # 关闭此状态的日志记录,避免干扰
        allow 127.0.0.1; # 只允许本地或内网 IP 访问
        deny all;
    }
}

重载 Nginx:nginx -s reload

步骤 2:验证状态页

访问 http://your_nginx_server:8080/nginx_status,输出示例:

Active connections: 291 
server accepts handled requests
 16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106 
  • Active connections: 当前活跃连接数
  • accepts/handled/requests: 总接收连接数/成功处理连接数/总请求数
  • Reading/Writing/Waiting: 正在读请求头/正在写响应/空闲等待的连接数

步骤 3:Prometheus 采集脚本

创建 nginx_status_exporter.py(Python 示例),定期抓取并暴露 Prometheus 指标:

from prometheus_client import start_http_server, Gauge
import requests
from time import sleep

# 定义 Prometheus 指标
NGINX_ACTIVE_CONN = Gauge('nginx_active_connections', 'Active connections')
NGINX_READING = Gauge('nginx_reading', 'Reading connections')
NGINX_WRITING = Gauge('nginx_writing', 'Writing connections')
NGINX_WAITING = Gauge('nginx_waiting', 'Waiting connections')
NGINX_ACCEPTS = Gauge('nginx_accepts_total', 'Total accepted connections')
NGINX_HANDLED = Gauge('nginx_handled_total', 'Total handled connections')
NGINX_REQUESTS = Gauge('nginx_requests_total', 'Total requests')

def scrape_nginx_status():
    try:
        resp = requests.get('http://localhost:8080/nginx_status', timeout=5)
        lines = resp.text.split('\n')
        # 解析第二行:server accepts handled requests
        accepts, handled, requests = map(int, lines[1].split()[1:])
        # 解析第三行:Reading: 6 Writing: 179 Waiting: 106
        reading, writing, waiting = map(int, lines[2].split()[1:])
        active = int(lines[0].split(':')[1].strip().split()[0])

        # 更新指标
        NGINX_ACTIVE_CONN.set(active)
        NGINX_READING.set(reading)
        NGINX_WRITING.set(writing)
        NGINX_WAITING.set(waiting)
        NGINX_ACCEPTS.set(accepts)
        NGINX_HANDLED.set(handled)
        NGINX_REQUESTS.set(requests)
    except Exception as e:
        print(f"Scrape error: {e}")

if __name__ == '__main__':
    start_http_server(9113)  # 暴露指标的端口
    while True:
        scrape_nginx_status()
        sleep(10)  # 每 10 秒采集一次

运行脚本后,Prometheus 可配置抓取 http://exporter_host:9113/metrics


2.2 方案二:Access Log 深度解析(推荐)

步骤 1:优化 Nginx Access Log 格式

自定义日志格式,包含关键指标(耗时、状态码、上游响应时间等):

http {
    log_format timed_combined '$remote_addr - $remote_user [$time_local] '
                            '"$request" $status $body_bytes_sent '
                            '"$http_referer" "$http_user_agent" '
                            '$request_time $upstream_response_time $upstream_addr';
    access_log /var/log/nginx/access.log timed_combined;
}
  • $request_time: 请求总耗时(秒,精确到毫秒)
  • $upstream_response_time: 上游服务器响应时间(秒)
  • $upstream_addr: 上游服务器地址

步骤 2:使用 Filebeat 采集日志

Filebeat 轻量高效,适合日志采集。配置 filebeat.yml

filebeat.inputs:
- type: log
  paths:
    - /var/log/nginx/access.log
  fields:
    service: nginx
output.logstash:
  hosts: ["logstash:5044"]  # 发送到 Logstash 或直接到 Elasticsearch

步骤 3:Logstash 解析日志(可选)

若需复杂处理(如 GeoIP 解析、字段拆分),用 Logstash 过滤:

input { beats { port => 5044 } }
filter {
  grok {
    match => { "message" => "%{COMBINEDAPACHELOG}" } # 或使用自定义正则解析 timed_combined
  }
  date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] }
  geoip { source => "clientip" } # 解析 IP 地理位置
}
output { elasticsearch { hosts => ["elasticsearch:9200"] } }

步骤 4:Prometheus + Loki 轻量方案

若倾向 Prometheus 生态,可用 Promtail(Loki 的 Agent)采集日志并转换为指标:

# promtail-config.yaml
server:
  http_listen_port: 9080
positions:
  filename: /tmp/positions.yaml
clients:
  - url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: nginx_access
  static_configs:
  - targets: [localhost]
    labels:
      job: nginx
      __path__: /var/log/nginx/access.log
  pipeline_stages:
    - regex:
        expression: '^(?P<ip>\S+) \S+ \S+ \[(?P<time>[^\]]+)\] "(?P<method>\S+) (?P<path>\S+) \S+" (?P<status>\d+) \S+ "(?P<referer>[^"]*)" "(?P<agent>[^"]*)" (?P<request_time>\S+) (?P<upstream_time>\S+) (?P<upstream_addr>\S+)'
    - metrics:
        - counter:
            name: nginx_requests_total
            description: "Total Nginx Requests"
            match_all: true
            labels:
              status: "$status"
              method: "$method"
        - histogram:
            name: nginx_request_duration_seconds
            description: "Nginx Request Duration"
            match_all: true
            buckets: [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10]

三、数据存储与可视化

3.1 Prometheus + Grafana(经典组合)

步骤 1:Prometheus 配置抓取任务

prometheus.yml 中添加:

scrape_configs:
  - job_name: 'nginx-stub-status'
    static_configs:
      - targets: ['exporter_host:9113']  # Stub Status Exporter
  - job_name: 'nginx-logs'  # 若用 Loki,此部分可省略,通过 Grafana 直接查 Loki

步骤 2:Grafana 仪表盘配置

导入官方 Nginx 仪表盘(ID: 12708)或自定义面板,核心图表包括:

  • QPS 趋势图​:rate(nginx_requests_total[1m])
  • 连接数实时图​:nginx_active_connections
  • 状态码分布​:sum by (status) (nginx_requests_total)
  • 请求耗时 P99​:histogram_quantile(0.99, rate(nginx_request_duration_seconds_bucket[1m]))

3.2 ELK Stack(深度日志分析)

  • Elasticsearch​:存储解析后的日志数据;
  • Kibana​:构建日志查询、可视化仪表盘(如 Top URL、错误请求热力图);
  • 优势​:支持全文检索、复杂聚合分析,适合审计与排障。

四、实时告警与自动化响应

4.1 Prometheus Alertmanager 告警规则

alert.rules.yml 示例:

groups:
- name: nginx_alerts
  rules:
  - alert: HighRequestLatency
    expr: histogram_quantile(0.95, rate(nginx_request_duration_seconds_bucket[1m])) > 2
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "Nginx 请求延迟过高"
      description: "95% 请求延迟超过 2 秒,当前值:{{ $value }}s"

  - alert: High5xxRate
    expr: rate(nginx_requests_total{status=~"5.."}[1m]) / rate(nginx_requests_total[1m]) > 0.05
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "Nginx 5xx 错误率过高"
      description: "5xx 错误率超过 5%,当前值:{{ $value | humanizePercentage }}"

4.2 告警通知集成

Alertmanager 支持邮件、Slack、PagerDuty、钉钉等,配置 alertmanager.yml

receivers:
- name: 'dingtalk-webhook'
  webhook_configs:
  - url: 'https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN'
    send_resolved: true
route:
  group_by: ['alertname']
  receiver: 'dingtalk-webhook'

4.3 自动化响应(进阶)

结合 ​Nginx Plus API​ 或 ​Lua 脚本,实现动态限流或熔断:

  • 当检测到 5xx 率过高时,自动触发 Nginx 限流规则(limit_req);
  • 当上游服务故障时,自动切换备用 upstream(需 Nginx Plus 或 OpenResty)。

五、项目落地 checklist

  1. 基础监控​:启用 Stub Status,部署 Exporter + Prometheus + Grafana;
  2. 日志增强​:自定义 Access Log 格式,集成 Filebeat/Logstash/Promtail;
  3. 可视化​:配置核心指标仪表盘(QPS、延迟、状态码、连接数);
  4. 告警闭环​:设置关键指标告警(延迟、错误率、连接数),集成通知渠道;
  5. 权限控制​:保护 Stub Status 页面和监控平台访问权限;
  6. 性能影响评估​:确保采集频率(如 10s/次)和日志量不影响 Nginx 性能;
  7. 文档沉淀​:记录指标含义、告警处理逻辑、排障流程。

六、总结

Nginx 实时请求监测项目的核心是​“数据驱动决策”​​:

  • 基础层用 Stub Status 快速感知连接与吞吐;
  • 深度层用 Access Log 分析业务细节与用户体验;
  • 可视化用 Grafana/ELK 直观呈现趋势与异常;
  • 自动化用告警与响应机制实现故障自愈。

通过这套实践方案,可构建从“被动救火”到“主动预防”的监控体系,为 Nginx 乃至整个 Web 服务的稳定性保驾护航。

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞77 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容