核心是让日志写入脱离请求处理路径,避免 worker 进程被磁盘 i/o 阻塞;通过启用 buffer=32k~64k 与 flush=1s~3s 组合缓冲、复用 open_log_file_cache、精简 log_format 和关闭低价值路径日志,并配合 ssd 独立分区、noatime 挂载及 copytruncate 日志轮转实现高效日志输出。

核心是让日志写入脱离请求处理路径,避免 worker 进程被磁盘 I/O 阻塞。不靠系统缓存“兜底”,而是用好 Nginx 自身的缓冲、复用、精简和协同机制。
启用带 flush 的 buffer 缓冲写入
这是最直接有效的手段。buffer 和 flush 必须同时配置,缺一不可:
- buffer=32k~64k:每个 worker 独立分配,QPS 5000 左右场景起步用 32k;若日志行较长(含 $request_body 或多个 upstream 变量),可升至 64k;超过 128k 易增加宕机丢志风险
- flush=1s~3s:推荐从 1s 开始——既能满足 WAF/SIEM 秒级采集需求,又能大幅降低刷盘频次;设为 5s 以上会拖慢异常行为响应,不符合基本安全 SLA
- 示例:access_log /var/log/nginx/access.log main buffer=64k flush=1s;
复用日志文件句柄,减少系统调用
频繁 open/close 日志文件会带来大量 syscalls,尤其在 logrotate 后容易引发争抢:
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- open_log_file_cache max=1000 inactive=20s min_uses=3 valid=1m;
- max=1000 适合多虚拟主机或按 location 分日志的场景
- valid=1m 确保每分钟检查一次文件是否存在,能自动适配 logrotate 创建的新文件
- min_uses=3 避免临时请求触发无效缓存
从源头精简日志内容与范围
少写比快写更治本:
- 自定义 log_format,只保留关键字段:$remote_addr、$time_local、$request、$status、$body_bytes_sent、$request_time
- 显式关闭低价值路径日志:location ~* \.(js|css|png|jpg|gif)$ { access_log off; }
- 用 map + log_if 过滤健康检查、爬虫 UA、内网探测流量
- error_log 级别设为 warn 或 error,禁用 info/debug(它不支持 buffer,会直接拖慢 worker)
配套系统与存储层优化
Nginx 层配置再好,也需底层支撑:
- 日志目录挂载到 独立 SSD 分区,避免与业务数据混用 IO 资源
- 挂载参数加 noatime(ext4)或等效选项,禁用访问时间更新
- logrotate 使用 copytruncate 模式,避免 rename 导致的写阻塞(需确认 Nginx 支持 reopen)
- 禁用 rsyslog/journald 对 access.log 的实时 tail,防止多进程抢文件句柄










