nginx非阻塞日志写入需配置access_log的buffer=64k flush=1s,并配合open_log_file_cache、精简log_format、静态资源关闭日志、error_log降级及logrotate安全轮转。

直接在 access_log 指令中启用 buffer 和 flush,就是 Nginx 原生支持的“非阻塞日志写入”方式。它不是靠额外线程或进程实现异步,而是让每个 worker 把日志先写进内存缓冲区,再按需批量刷盘,从而避免每次请求都触发磁盘 write() 系统调用。
用 buffer + flush 控制写入节奏
这是最核心、最有效的配置项,必须加在 access_log 行末:
-
buffer=64k:为每个 worker 分配最多 64KB 内存缓存日志;单行日志平均 200B 左右时,可暂存约 300 条请求记录 -
flush=1s:即使缓冲未满,每秒也强制落盘一次;对万级 QPS 服务,1s 是延迟与可靠性较优的平衡点 - 示例:
access_log /var/log/nginx/access.log main buffer=64k flush=1s;
配合 open_log_file_cache 复用文件句柄
避免高频 open()/close() 系统调用开销,尤其在多虚拟主机或多日志路径场景下:
-
max=1000:最多缓存 1000 个日志文件描述符 -
inactive=30s:30 秒内未使用的 fd 自动释放 -
valid=1m:每分钟检查一次缓存项是否仍指向有效文件(兼容 logrotate) - 需放在
http块顶层,全局生效
精简日志内容,从源头减负
写得少,自然压得低。高并发下应只保留诊断必需字段:
- 自定义
log_format,去掉$http_user_agent、$http_referer等体积大、价值低的字段 - 静态资源路径显式关闭日志:
location ~* \.(js|css|png|jpg|gif)$ { access_log off; } -
error_log级别设为warn或error,禁用info/debug
轮转与信号协同,避免 reload 引发写混乱
频繁 nginx -s reload 会导致新旧 worker 同时往同一文件路径写,虽不报错但易穿插、难排查:
- logrotate 中使用
postrotate nginx -s reopen或直接发kill -USR1 $(cat /var/run/nginx.pid) - 确保
reopen能安全重开所有 worker 的日志 fd,不丢日志也不交错 - 若用
copytruncate,需确认 Nginx 版本 ≥ 1.15.0 且内核支持原子截断
不复杂但容易忽略











