Nginx高并发性能抖动主因是access_log无缓冲直写磁盘,需检查配置是否含buffer/flush参数、验证小IO是否消失、排除error_log和重复日志干扰,并通过lsof和iostat确认缓冲生效。

排查 Nginx 高并发下因日志缓冲区满引发的性能抖动,核心是确认 access_log 缓冲是否成为 I/O 瓶颈,而不是简单看日志文件大小或磁盘空间。抖动表现为请求延迟毛刺、P99 波动、iowait 升高,但 CPU 和内存使用率未必异常。
盯住 access_log 缓冲实际效果
默认配置下 access_log 是无缓冲直写磁盘的,高并发时会生成海量小 IO。先检查当前是否启用缓冲:
- 在 nginx.conf 的 http 或 server 块中查找
access_log指令,确认是否带buffer=64k flush=5s参数 - 若只有路径(如
access_log /var/log/nginx/access.log;),说明完全无缓冲,就是抖动首要嫌疑 - 用
nginx -T | grep access_log查看生效配置,注意 include 的子配置可能覆盖主配置
验证缓冲是否被频繁刷盘或溢出
即使配了 buffer,也可能因参数不当失效:
- 运行
iotop -o -p $(pgrep nginx),观察 worker 进程的 WRITE 活动是否集中在日志文件上;若持续有 1–4KB 小写,说明缓冲未生效或被强制刷新 - 查系统日志:
dmesg -T | grep -i "buffer.*full\|log.*overflow",部分内核或高版本 Nginx 会在缓冲压满且无法及时刷盘时记录警告 - 临时加字段到日志格式:
log_format debug '$request_time $upstream_response_time $bytes_sent $request_length';,再用日志分析工具筛选$request_time > 0.5但$bytes_sent < 1024的请求——这类响应快但日志写入慢的请求,常卡在缓冲排队中
排除其他日志干扰源
error_log、调试日志、子 location 日志都可能悄悄放大 IO:
- 检查
error_log级别是否为debug或info;生产环境应设为warn或更高,避免 proxy_pass/SSL 握手等细节刷爆磁盘 - 确认静态资源(
.js、.css、/healthz)所在 location 是否明确写了access_log off; - 搜索配置中是否有重复
access_log指令(例如 http 块和 server 块都配了),会导致同一次请求写多次日志
快速验证与收口
改完配置后,不重启也能验证缓冲是否起效:
- 执行
nginx -s reload生效新配置 - 用
lsof -p $(pgrep nginx | head -1) | grep access.log看日志文件是否仍处于REG状态且偏移量缓慢增长(说明是批量写);若偏移量跳变频繁,说明仍是小写 - 压测 1 分钟后对比
iostat -x 1 5中对应磁盘的await和%util,下降明显即缓冲生效



















