nginx access_log 是真实消耗资源的硬瓶颈,尤其在高频小包 api 场景下;/api 路径禁用可降 cpu 12%~18%、p99 延迟减 7ms;应直接 location 内设 access_log off,避免 log_if;缓冲写(buffer+flush)和精简日志格式可显著优化性能。

Nginx 的 access_log 不是“可有可无”的旁路记录,而是请求处理链路上一个真实消耗 CPU、内存和 I/O 的环节。它对吞吐量的制约不是理论上的,而是可测量、可优化的硬瓶颈——尤其在高频小包 API 场景下。
/api 路径禁用 access_log 能显著释放吞吐能力
高频接口(如心跳、埋点、轮询)每秒可能产生数千次短请求。每次 access_log 写入都要经历:格式化变量(解析 $time_local、$request_time 等)、调用 write() 或缓冲写、触发磁盘 I/O(即使 SSD 也有延迟)、管理日志缓冲区锁与刷盘逻辑。
实测表明:在 5k+ QPS 的纯 JSON 接口下,仅对 /api/ 块设置 access_log off;,worker 进程 CPU 使用率下降 12%~18%,P99 延迟减少约 7ms。
- ✅ 正确做法:在具体
location /api/块中直接写access_log off; - ❌ 错误做法:用
log_if过滤/api—— 格式化仍执行,开销不减;或全局关日志再单独开启其他路径 —— 维护难、易遗漏
buffer + flush 配合可大幅降低 I/O 频次但不消除开销
若业务必须保留 /api 日志(如审计要求),可用缓冲批量写替代逐条落盘:
-
access_log /path/log.log main buffer=64k flush=1s;
这会让日志先暂存内存,满 64KB 或超 1 秒就批量刷盘,把高频小写聚合成低频大写。 - buffer 太小(256k)增加宕机丢志风险
- flush 必须配 buffer,否则日志可能卡在内存里数秒甚至更久
日志格式精简比压缩更有效且零额外 CPU 成本
去掉 $http_user_agent、$http_referer 等长而低价值字段,自定义紧凑格式:
log_format compact '$remote_addr [$time_local] "$request" $status $body_bytes_sent $request_time'; access_log /var/log/nginx/access.log compact buffer=128k flush=5s;
单条日志体积下降 30%~50%,磁盘写入量和解析开销同步降低,且不增加 Nginx 的 CPU 压力。
- Nginx 层
gzip日志不推荐:同步压缩抬高 CPU,压缩率仅 40%~60%,还破坏tail -f实时可观测性
日志归档应交给 logrotate,而非 Nginx
真正节省 90% 存储空间的方案是分层处理:
- Nginx 明文输出 + 大 buffer + 合理 flush
- logrotate 每日轮转后异步调用系统
gzip批量压缩(压缩率 88%~92%) - 配合
delaycompress避免重复压缩
不复杂但容易忽略











