Nginx 应作为 WebSocket 透明管道,关闭缓冲(proxy_buffering off; proxy_buffer_size 0; proxy_buffers 8 0;)、禁用缓存(proxy_cache off)、清空扩展头(proxy_set_header Sec-WebSocket-Extensions "")、设严格超时(proxy_read_timeout 60; proxy_send_timeout 10;)、限制上游长连接(upstream keepalive 32;)、前置限频,并关闭日志以压低内存开销。

核心是让 Nginx 只做“透明管道”,不参与业务逻辑、不缓存、不解析、不压缩,把内存开销压到最低。
精简代理职责:关掉所有非转发功能
Nginx 不是应用服务器,不该承担鉴权、广播、消息解码或压缩任务。这些都该由后端服务完成:
- 显式清空 WebSocket 扩展头:
proxy_set_header Sec-WebSocket-Extensions "",避免 permessage-deflate 压缩上下文在代理层堆积内存 - 关闭缓冲:
proxy_buffering off;,再加proxy_buffer_size 0;和proxy_buffers 8 0;,杜绝帧级缓存 - 跳过 URL 路由与重写:所有
/ws/*统一透传,不做 path 分析或鉴权,路由逻辑交给后端网关 - 禁用缓存:
proxy_cache off;,防止 Upgrade 请求被意外缓存
收紧连接生命周期:防“僵尸连接”拖垮内存
内存上涨往往不是因为活跃连接多,而是大量已断开却未清理的连接滞留。Nginx 需主动干预:
- 设严格超时:
proxy_read_timeout 60;(握手+空闲总时长上限),proxy_send_timeout 10;,避免发心跳卡住阻塞 worker - 限制上游连接复用:
upstream { keepalive 32; },控制每个 worker 到后端的最大长连接数,防连接池爆炸 - 前置限频:
limit_req zone=ws_conn burst=5 nodelay;,按 IP + User-Agent 限制建连频率(如 5 次/分钟),过滤爬虫或异常重连
优化底层内存分配:减少碎片与小块分配
worker 进程频繁申请小 buffer 是内存碎片主因,需从运行时层面调控:
- 固定 buffer 大小:
proxy_buffer_size 4k;,proxy_buffers 8 4k;,避免动态扩容导致堆碎片 - 调大初始堆空间:启动时加
-g "worker_rlimit_core 2G;",并指定working_directory /var/tmp;,便于后续分析 core dump - 关闭日志:
access_log off;,error_log /dev/null warn;,消除高频字符串拼接和 I/O 内存分配
分层监控定位真实瓶颈
不能只看总内存,要盯住进程级健康指标:
- 采集
process_resident_memory_bytes和nginx_connections_active,观察内存增长是否与连接数线性相关 - 用
gdb -p $(pgrep nginx)查 worker 是否卡在SSL_read或epoll_wait,确认是否 SSL 握手或系统调用阻塞 - 检查
ss -s | grep "tw",若 TIME_WAIT 过多,需调优内核参数:net.ipv4.tcp_tw_reuse = 1和net.ipv4.ip_local_port_range


















