广告位 · 页头(后台-模块管理-新建模块后替换此区域)

如何借助node_exporter采集Nginx所在主机的系统指标?

在排查Nginx性能问题时,不少同学习惯直接查看nginx_status或者访问日志,但连接数和请求量只能反映应用层压力。比如一台Nginx主机连接数很低,却出现响应变慢,很可能是CPU软中断处理网卡队列时被打满,或者磁盘IO等待升高导致日志写入变慢。这些操作系统层面的指标不会出现在Nginx的状态页里,只能借助专门的主机监控采集器获取。

如何借助node_exporter采集Nginx所在主机的系统指标?

node_exporter就是Prometheus生态中负责暴露主机系统指标的组件。它以守护进程方式运行在Nginx所在的Linux服务器上,通过HTTP接口对外提供/metrics数据。Prometheus定期拉取这些数据,就可以获得CPU使用率、内存剩余量、磁盘空间、网络吞吐、文件系统读写延迟等关键信息。结合Nginx自身的stub_status模块,就能同时看到应用层连接状态与系统资源消耗,定位问题时不再靠猜测。

部署node_exporter与Prometheus抓取

node_exporter不需要复杂依赖,官方提供编译好的二进制文件。以Linux x86_64平台为例,下载并解压后放到/usr/local/bin目录即可。建议创建独立系统用户运行,避免使用root权限。

# 下载node_exporter二进制包(替换版本号)
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar -zxvf node_exporter-1.8.2.linux-amd64.tar.gz
sudo cp node_exporter-1.8.2.linux-amd64/node_exporter /usr/local/bin/
sudo useradd -rs /bin/false node_exporter

创建systemd服务文件/etc/systemd/system/node_exporter.service,内容如下。注意ExecStart后要写完整路径,--web.listen-address可以自定义监听端口,默认9100。如果服务器有多张网卡,建议绑定内网IP,避免暴露到公网。

[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter --web.listen-address=:9100
[Install]
WantedBy=multi-user.target

执行systemctl daemon-reload、systemctl start node_exporter、systemctl enable node_exporter后,通过curl http://127.0.0.1:9100/metrics就能看到大量指标。接着在Prometheus配置文件中添加一个job,让Prometheus定期抓取Nginx主机上的node_exporter。示例配置如下,targets替换为实际IP地址。

scrape_configs:
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['192.168.10.10:9100']
        labels:
          service: 'nginx-host'

抓取间隔可以根据服务器规模调整,通常15秒到30秒即可。如果Nginx主机数量较多,建议配合Prometheus的文件服务发现或Consul自动发现,避免手动维护targets列表。

开启Nginx状态页与关键指标解读

Nginx默认不开启状态页,需要在配置文件中增加一个location块。通常做法是单独监听一个内网端口或者限制访问来源IP,防止状态数据暴露。下面的配置在Nginx中启用stub_status模块,只允许Prometheus服务器访问。

server {
    listen 8080;
    server_name 127.0.0.1;
    allow 192.168.10.20;
    deny all;
    location /nginx_status {
        stub_status;
        access_log off;
    }
}

保存后执行nginx -t并reload,访问http://127.0.0.1:8080/nginx_status可以看到类似Active connections: 12、server accepts handled requests等内容。其中Active connections表示当前活跃连接数,accepts是累计接受连接数,handled是累计处理连接数,requests是累计请求数。Reading、Writing、Waiting三个值分别表示正在读取请求头、正在写响应、以及keep-alive等待的连接数。

再看node_exporter提供的系统指标。CPU使用率可以从node_cpu_seconds_total计算得出,这个计数器按CPU核心和模式(user、system、idle、iowait等)分别累加时间。用rate(node_cpu_seconds_total{mode="idle"}[5m])可以得到idle占比,再用1减去idle比例就是整体CPU使用率。内存方面,node_memory_MemAvailable_bytes表示不考虑缓存回收时的可用内存,比传统的MemFree更接近真实可用量。磁盘空间用node_filesystem_avail_bytes结合node_filesystem_size_bytes计算使用百分比。磁盘IO等待则需要关注node_disk_io_time_seconds_total,该指标累计磁盘繁忙时间,配合rate()可以看出磁盘是否成为瓶颈。

网络指标同样关键。node_network_receive_bytes_total和node_network_transmit_bytes_total分别记录网卡累计接收和发送字节数。Nginx作为反向代理时,如果网络吞吐突然打满网卡带宽,即使CPU和内存空闲,请求也会排队超时。因此查看系统指标时要同时关注CPU、内存、磁盘IO和网络四个维度,而不是单独看某一项。

联合指标定位问题与告警规则

把Nginx状态页指标和node_exporter指标放在同一个Grafana仪表盘中,可以快速判断故障类型。例如Nginx的Active connections突然飙升,同时node_network_receive_bytes_total的速率接近网卡上限,说明可能是流量突增或遭受攻击。如果Active connections不高,但CPU的iowait占比持续超过20%,则需要检查磁盘IO,比如日志盘是否性能不足、是否开启了Nginx错误日志的同步写入。

另一种典型场景是内存泄漏。Nginx自己的worker进程通常内存占用稳定,但如果主机上还有其他服务,或者Nginx加载了第三方模块出现内存增长,node_memory_MemAvailable_bytes会持续下降。结合node_memory_SwapUsed_bytes观察是否开始使用交换分区,一旦出现Swap使用,性能会断崖式下降。此时可以结合ps命令进一步定位具体进程。

下面给出两条Prometheus告警规则示例,分别用于主机内存不足和磁盘空间不足。规则文件通过rule_files加载到Prometheus中。

groups:
  - name: nginx_host_alerts
    rules:
      - alert: HostMemoryLow
        expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "主机内存可用率低于10%"
          description: "实例 {{ $labels.instance }} 当前可用内存仅 {{ $value }}%"
      - alert: HostDiskSpaceLow
        expr: node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} * 100 < 10
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "磁盘空间不足"
          description: "实例 {{ $labels.instance }} 挂载点 {{ $labels.mountpoint }} 剩余空间不足10%"

上面的表达式中使用了<表示小于,注意在Prometheus配置文件中可以直接写<或者转义为<,PromQL本身支持。规则触发后可以通过Alertmanager发送邮件、企业微信或钉钉通知。

实际生产环境中,建议把node_exporter的--collector.disable-defaults和--collector.filesystem.ignored-mount-points等参数利用起来,过滤掉不需要的挂载点和设备,减少指标数量。同时为Prometheus设置合理的scrape_interval和retention.time,避免监控数据占用过多磁盘。

广告位 · 文章底部(后台-模块管理替换此区域)