7.7.8 观测与压测:指标、火焰图与压力测试方法
本节围绕“观测与压测”建立可复用的诊断与压测方法体系,覆盖指标、采集、火焰图、压力测试与结果解读,形成从观测到优化的闭环,并提供安装、命令解释、排错与练习。
一、原理草图:观测与压测闭环
二、指标体系与观测维度(含示例)
- 访问层:QPS、并发连接、P95/P99、错误率
- 资源层:CPU、内存、I/O、网络
- Nginx:active/reading/writing/waiting、accepts/handled/requests
- 业务层:核心接口延迟、成功率
- 日志关联:access/error/上游日志时间对齐
示例:快速查看 Nginx stub_status
# 1) Nginx 配置启用 stub_status
cat >/etc/nginx/conf.d/status.conf <<'EOF'
server {
listen 127.0.0.1:8080;
location /stub_status {
stub_status;
access_log off;
allow 127.0.0.1;
deny all;
}
}
EOF
# 2) 语法检查与重载
nginx -t
nginx -s reload
# 3) 访问查看指标
curl -s http://127.0.0.1:8080/stub_status
# 预期输出示例:
# Active connections: 2
# server accepts handled requests
# 100 100 500
# Reading: 0 Writing: 1 Waiting: 1
命令解释
- stub_status:输出连接与请求统计
- accepts/handled/requests:接收/处理/累计请求数
- Reading/Writing/Waiting:读/写/空闲连接数
三、观测与数据采集方案(安装与配置示例)
1)Prometheus + Nginx Exporter(推荐)
# 安装 nginx-prometheus-exporter(以二进制为例)
wget -q https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v1.1.0/nginx-prometheus-exporter_1.1.0_linux_amd64.tar.gz
tar -xf nginx-prometheus-exporter_1.1.0_linux_amd64.tar.gz -C /usr/local/bin
# 启动 exporter,抓取 stub_status
/usr/local/bin/nginx-prometheus-exporter \
-nginx.scrape-uri http://127.0.0.1:8080/stub_status \
-web.listen-address=:9113 &
# 验证
curl -s http://127.0.0.1:9113/metrics | head
Prometheus 采集配置示例
# /etc/prometheus/prometheus.yml
scrape_configs:
- job_name: 'nginx'
static_configs:
- targets: ['127.0.0.1:9113']
2)日志指标化(示例:统计 P99 与错误码)
# 统计 5xx 比例(示例从 access.log)
awk '{print $9}' /var/log/nginx/access.log | \
awk '$1 ~ /^5/ {c++} END {print "5xx:", c}'
# 统计 request_time P99(假设 request_time 为最后一列)
awk '{print $NF}' /var/log/nginx/access.log | sort -n | \
awk 'NR==int(NR*0.99) {print "P99:", $1}'
排错提示
- 若 stub_status 无法访问,检查 listen 与 allow/deny 是否正确。
- 若 exporter 无数据,确认 nginx -t 通过且 /stub_status 可用。
四、火焰图与热点定位(安装与示例)
1)安装 perf 与 FlameGraph
# Debian/Ubuntu
apt-get update && apt-get install -y linux-tools-common linux-tools-$(uname -r) git
# CentOS/RHEL
yum install -y perf git
# FlameGraph
git clone https://github.com/brendangregg/FlameGraph.git /opt/FlameGraph
2)采集 On-CPU 火焰图
# 采集 60s CPU 样本
perf record -F 99 -p $(pgrep -o nginx) -g -- sleep 60
# 生成火焰图
perf script | /opt/FlameGraph/stackcollapse-perf.pl | \
/opt/FlameGraph/flamegraph.pl > /tmp/nginx_cpu.svg
# 打开 /tmp/nginx_cpu.svg 查看热点函数
3)Off-CPU(等待/锁/I/O)
perf record -e sched:sched_switch -a -- sleep 60
perf script | /opt/FlameGraph/stackcollapse-perf.pl | \
/opt/FlameGraph/flamegraph.pl > /tmp/nginx_offcpu.svg
排错提示
- perf 权限不足:临时开启 echo 0 > /proc/sys/kernel/perf_event_paranoid(注意安全)
- 火焰图无符号:安装调试符号或确认二进制未被 strip
五、压力测试设计与方法(含命令与解释)
1)工具安装
# wrk (压测静态/代理)
apt-get install -y wrk || yum install -y wrk
# k6 (脚本化压测)
curl -s https://api.github.com/repos/grafana/k6/releases/latest | \
grep browser_download_url | grep linux-amd64 | cut -d '"' -f 4 | \
xargs wget -O /tmp/k6.tgz
tar -xf /tmp/k6.tgz -C /usr/local/bin --strip-components=1
2)wrk 压测示例
# 并发 200,持续 60 秒,10 线程
wrk -t10 -c200 -d60s http://127.0.0.1/
# 关键输出解释:
# Requests/sec: 吞吐
# Latency: 平均延迟
# 99%: 尾延迟
3)k6 压测示例(带断言)
// /opt/k6/http_test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = { vus: 100, duration: '60s' };
export default function () {
let res = http.get('http://127.0.0.1/');
check(res, { 'status is 200': (r) => r.status === 200 });
sleep(1);
}
k6 run /opt/k6/http_test.js
4)阶梯式加压脚本
# /opt/bench/step_load.sh
#!/bin/bash
URL="http://127.0.0.1/"
for c in 50 100 200 400; do
echo "== Concurrency: $c =="
wrk -t10 -c$c -d30s $URL
sleep 10
done
chmod +x /opt/bench/step_load.sh
/opt/bench/step_load.sh
六、压测结果解读与优化闭环(含对照命令)
1)瓶颈识别对照
# CPU/内存
top -p $(pgrep -o nginx)
# I/O
iostat -x 1 5
# 网络
ss -s
判断逻辑
- CPU 高、iowait 低:CPU 计算或加密瓶颈(如 gzip、ssl)
- iowait 高:磁盘或日志写入瓶颈
- ESTAB/TimeWait 过多:连接管理或上游响应慢
2)日志定位慢请求
# 过滤 request_time > 1s
awk '$NF > 1 {print $0}' /var/log/nginx/access.log | head
3)优化回归
# 改动后执行小规模回归
wrk -t5 -c50 -d30s http://127.0.0.1/
七、常见故障排查清单(压测中)
- 502/504 增多:检查上游健康、proxy_connect_timeout/proxy_read_timeout
- 连接耗尽:检查 worker_connections 与 ulimit -n
- 日志写入阻塞:开启 access_log off 或异步日志缓冲
示例:
access_log /var/log/nginx/access.log main buffer=128k flush=5s;
八、练习与自测
1. 启用 stub_status,采集 1 分钟 QPS 与 active 变化。
2. 使用 wrk 完成 50/100/200 并发阶梯压测,记录拐点。
3. 采集一次 On-CPU 火焰图,标注热点函数。
4. 从 access.log 中找出 P99 请求时间,并指出慢 URI。
5. 调整 worker_connections 后回归压测,比较吞吐提升。