7.7.1 典型故障定位流程与日志分析方法

典型故障定位流程可遵循“现象确认—影响范围—变更回溯—证据采集—根因验证—修复与复盘”的闭环。建议先固化一个可执行的排查模板,并在日志格式、系统指标和上游链路之间建立可关联的字段(如 request_id)。

文章图片

1. 环境准备与日志格式示例#

若需安装常用分析工具与确保 Nginx 日志字段完备,建议先完成以下步骤(以 Ubuntu 为例):

# 安装基础工具
sudo apt-get update
sudo apt-get install -y nginx jq git

# 校验 Nginx 配置并查看生效配置
sudo nginx -t
sudo nginx -T | sed -n '1,120p'

配置建议包含上游耗时与 request_id,便于链路追踪(/etc/nginx/nginx.conf):

http {
    log_format main_ext '$time_local '
                        '$remote_addr '
                        '"$request" '
                        '$status '
                        '$body_bytes_sent '
                        '$request_time '
                        '$upstream_response_time '
                        '$upstream_status '
                        '$upstream_addr '
                        '$http_user_agent '
                        '$request_id';

    access_log /var/log/nginx/access.log main_ext;
    error_log  /var/log/nginx/error.log warn;

    # 可配合应用生成 request_id
    map $http_x_request_id $request_id {
        default $http_x_request_id;
        ""      $request_id;
    }
}

说明:
- $request_time:Nginx 处理请求总耗时(秒)
- $upstream_response_time:上游响应耗时,快速判断瓶颈位置
- $upstream_addr:定位异常后端节点

2. 典型故障定位流程(带命令)#

2.1 现象确认与影响面#

# 统计 5xx 错误比例
awk '{print $9}' /var/log/nginx/access.log | grep -E '5..' | wc -l

# 统计某时段错误(例如 12:00-12:10)
awk '$4 >= "[10/Mar/2025:12:00" && $4 <= "[10/Mar/2025:12:10"' \
    /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c

解释:先确定错误比例与窗口,避免盲目扩大排查范围。

2.2 变更回溯#

# 查 Nginx 配置变更时间
ls -lt /etc/nginx

# 若使用 Git 管理配置
cd /etc/nginx
git log -p -n 3

解释:与故障时间点对齐,定位最近一次配置或证书变更。

2.3 证据采集(日志、系统、上游)#

# 错误日志关键字聚合
grep -E "connect\(\) failed|upstream timed out|no live upstreams" \
    /var/log/nginx/error.log | tail -n 50

# 系统资源采集
top -b -n 1 | head -n 15
vmstat 1 5
iostat -x 1 3
ss -s

解释:日志提供故障类型,系统指标判断是否为资源瓶颈。

3. 日志分析方法与示例#

3.1 状态码分布#

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head

期望效果:输出 200/4xx/5xx 统计,判断主要错误类型。

3.2 慢请求 TopN(基于 request_time)#

# 假设 $NF 为 request_id,$7URI,$9 为 status,$6 为 request_time
awk '{print $6,$7,$9,$NF}' /var/log/nginx/access.log | sort -nr | head

解释:定位耗时最高的接口或请求。

3.3 上游节点异常定位#

# 统计 5xx 的上游地址分布
awk '{print $8,$9}' /var/log/nginx/access.log | grep 5.. | sort | uniq -c | sort -nr

解释:如果某个 upstream_addr 集中出现 5xx,优先排查该实例。

3.4 单请求链路追踪#

# 用 request_id 关联多层日志
REQID="b3b5c3a1"
grep "$REQID" /var/log/nginx/access.log
grep "$REQID" /var/log/nginx/error.log

4. 典型故障与排错示例#

4.1 502/504 与上游超时#

# 查 error_log 中 upstream timed out
grep -n "upstream timed out" /var/log/nginx/error.log | tail -n 20

# 查看上游是否健康
curl -i http://10.0.0.11:8080/health

可能原因:上游服务卡顿/线程池耗尽/连接耗尽。

临时修复(谨慎评估):

# /etc/nginx/conf.d/upstream.conf
upstream app_backend {
    server 10.0.0.11:8080 max_fails=2 fail_timeout=5s;
    server 10.0.0.12:8080 max_fails=2 fail_timeout=5s;
}

server {
    location / {
        proxy_connect_timeout 3s;
        proxy_read_timeout 10s;
        proxy_send_timeout 10s;
        proxy_pass http://app_backend;
    }
}

解释:缩短超时或设置更合理的 failover;验证后再做长远优化。

4.2 “no live upstreams”#

grep -n "no live upstreams" /var/log/nginx/error.log

排查步骤:
1. 确认 upstream 后端是否全部不可达
2. 查看 max_failsfail_timeout 是否过于严格
3. 确认防火墙与安全组策略

4.3 连接拒绝(111 Connection refused)#

grep -n "Connection refused" /var/log/nginx/error.log
ss -antp | grep 8080

解释:端口未监听或进程崩溃,需检查上游服务状态。

5. 最小化验证与回滚策略#

# 小步调整配置后先验证
sudo nginx -t
sudo systemctl reload nginx

# 若验证失败,快速回滚
sudo cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf
sudo nginx -t && sudo systemctl reload nginx

说明:一次只改一项参数,避免引入新的不确定性。

6. 练习与自测#

  1. 生成 3 条不同状态码的访问日志,并统计 4xx/5xx 比例。
  2. 构造一个上游慢响应接口,抓取并输出 Top5 慢请求。
  3. 修改 log_format 添加 $upstream_response_time,验证日志是否生效。
  4. 将某 upstream 节点停止,观察 error_log 中的错误类型与 access_log 的变化。

练习验证命令示例:

# 模拟请求
curl -I http://localhost/
curl -I http://localhost/notfound
curl -I http://localhost/api/slow

# 统计 4xx/5xx
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr