应优先用内存管道替代磁盘写入,并按location精准关闭非关键路径日志;如healthz、静态资源等,配合极简log_format与禁用昂贵变量,可提升qps 5%–15%,降低p99延迟2–8ms。

直接把 access_log 写进磁盘是网关性能的隐形拖累,尤其在高并发、低延迟场景下。真正有效的优化不是“少记点”,而是“不落盘”或“精准记”。核心思路就两条:用内存管道替代文件写入,以及按需关闭非关键路径的日志输出。
用 memory-based pipe 替代文件句柄
Nginx 本身不原生支持“内存日志”,但可通过 named pipe(FIFO)+ 用户态日志收集器 实现等效效果。本质是把 access_log 指向一个内存管道,由轻量进程(如 socat、rsyslog 或自研 collector)实时读取、缓冲、批量落盘或转发。
- 创建命名管道:
mkfifo /var/log/nginx/access_pipe,并确保 nginx worker 进程有读权限 - 配置 Nginx:
access_log /var/log/nginx/access_pipe buffer=64k flush=1s;—— buffer 和 flush 控制写入节奏,避免频繁系统调用 - 后台启动消费端,例如:
cat /var/log/nginx/access_pipe | fluent-bit -i stdin -o elasticsearch ... & - 注意:管道不可 seek,且无内置持久化;若下游崩溃,数据会丢失,适合容忍少量丢失的监控/分析场景
按 location 精准开关 access_log
不是所有请求都值得记录。健康检查、静态资源、预检请求(OPTIONS)、内部探针等,日志价值极低,却消耗 I/O 和 CPU(格式化、锁竞争、写系统调用)。
使用tbot机器ID身份文件配合tsh CLI,通过Teleport访问控制SSH登录托管主机或执行远程命令。
- 在对应 location 块中显式关闭:
access_log off; - 典型可关场景:
location = /healthz { access_log off; return 200 "ok"; } - 对静态资源统一管理:
location ~* \.(js|css|png|jpg|gif|ico)$ { access_log off; expires 1h; } - 注意:
off是继承链终止指令,子 location 不会自动继承父级 on 状态;建议在 http 块设默认 on,再逐个 location 显式关
补充:更激进但有效的组合策略
单靠关日志或换管道还不够,配合其他轻量化手段才能释放全部潜力。
- 禁用日志变量中的昂贵字段:避免
$request_time、$upstream_response_time在非调试期使用(它们触发额外计时与上下文切换) - 用 log_format 定义极简格式,仅保留必要字段(如
$remote_addr $time_iso8601 "$request" $status $body_bytes_sent),减少字符串拼接开销 - 启用
log_subrequest on;仅当真需记录子请求时才开;默认为 off,多数代理场景无需开启 - 考虑将 access_log 移到 shared memory log(OpenResty 的
log_by_lua_block+ shm 缓存),实现毫秒级异步聚合写入
这些改动不改变业务逻辑,但能让单机 QPS 提升 5%–15%,P99 延迟下降 2–8ms,尤其在万级 RPS 网关上效果显著。关键不在“做没做”,而在“关得准、转得稳、格式轻”。










