← 中文资源

简体中文版本

诊断 nginx 日志中的 499 客户端中断

在 nginx 访问日志中定位 499 记录,与上游响应时长关联分析,判断是客户端超时过早还是服务端过慢。

阅读英文原文

目标

当用户放弃并关闭连接时,nginx 记录 499,而应用根本没完成这个请求,于是业务指标一片绿、体验却在恶化。从访问日志里挖出 499 并关联 upstream_response_time,就能分辨真实故事:客户端对真正慢的响应失去耐心,还是客户端超时设置得比工作所需更短。

步骤要点

  1. 用 awk 按“小时 + URI”聚合 499 记录,找出丢失客户端最多的端点与尖峰起始时间。
  2. 提取这些 499 的 upstream_response_time:若聚在 9.9 或 10.0 这类整数附近,说明有东西恰好在十秒超时。
  3. 对同端点的 200 响应统计上游耗时均值:若成功请求平均 12 秒,则服务端确实慢,而非客户端没耐心。
  4. 用 curl 直接测源站 ttfb 复核,排除 nginx 自身,把延迟问题移交应用侧修复或改为异步任务。
  5. 把按端点统计的 429 与 499 比率接入告警,避免只盯 5xx 的仪表盘漏掉体验恶化。

排错提示

日志里完全没有 499 多半是日志格式缺 status 字段或被级别过滤,应切到含 upstream_response_time 与 request_time 的 JSON 格式;499 尖峰但上游很快则要查调用方 SDK 默认超时与中间代理读超时;upstream_response_time 在未联系上游时为空,awk 处理前要做空值守卫。注意响应被客户端重试成功也会掩盖 499,需同时观察重复请求率。

适用边界

499 只记录“客户端中断了”,不记录“为什么”,原因要靠客户端日志或关联 id 补充;激进重试可能让 499 被后续成功掩盖,需配合重复请求率观察。

代码示例

# 499 per endpoint and hour
awk '$9 == 499 {print substr($4,2,14), $7}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -20