核心是让nginx只做“透明管道”,禁用缓冲、压缩、缓存、日志等非转发功能,精简代理职责;显式清空websocket扩展头、设proxy_buffer_size 0、proxy_buffers 8 0、关闭proxy_buffering;严格控制超时、限频、上游复用数,并优化底层内存分配减少碎片。

核心是让 Nginx 只做“透明管道”,不存状态、不缓存帧、不参与业务逻辑。内存暴涨往往不是连接数多,而是代理层悄悄做了不该做的事——比如压缩上下文、缓冲小帧、反复分配碎片内存。
精简代理职责,禁用所有非转发功能
WebSocket 代理不是应用服务器,它的唯一任务是把字节流从客户端原样送到后端,再原样送回。
- 显式清空 WebSocket 扩展头:
proxy_set_header Sec-WebSocket-Extensions "",防止 permessage-deflate 在代理内部维持压缩上下文 - 关闭响应缓冲:
proxy_buffering off;,并设proxy_buffer_size 0;和proxy_buffers 8 0;,避免 Nginx 为每个连接预分配 buffer - 跳过 URL 解析与鉴权:所有
/ws/路径统一透传,不做 path 匹配或 header 检查;路由和权限由后端网关处理
控制连接生命周期,主动清理无效连接
大量“建了却不活”的连接最耗内存——它们占着 fd、挂着 buffer、却不再收发数据。
- 设严格超时:
proxy_read_timeout 60;(握手 + 空闲总时长上限),proxy_send_timeout 10;(防发心跳卡死) - 限制上游连接复用数:
upstream { keepalive 32; },避免每个客户端独占一条后端连接 - 前置限频:
limit_req zone=ws_conn burst=5 nodelay;,按 IP 限制建连频率(如 5 次/分钟),过滤爬虫或异常重连
优化底层内存分配,减少碎片堆积
Nginx worker 进程频繁分配小 buffer(如 4KB 帧)会导致堆内存碎片化,RSS 持续上涨却难回收。
- 调大初始堆空间:启动时加
-g "worker_rlimit_core 2G;",并指定working_directory /var/tmp; - 固定 buffer 尺寸:在 upstream 中设
proxy_buffer_size 4k;和proxy_buffers 8 4k;,避免动态扩容 - 关闭日志写入:
access_log off;,error_log /dev/null warn;,消除高频字符串拼接和 I/O 分配开销
分层监控,快速定位真实瓶颈
别只看总内存,要盯住进程级健康指标:
- 定期采集
nginx_connections_active和process_resident_memory_bytes(Prometheus) - 用
pstack <pid></pid>查 worker 是否卡在SSL_read—— 若大量线程停在这,说明 TLS 握手阻塞,需换 ECDSA 证书或升级 OpenSSL - 配合
nginx -s status观察活跃连接分布,确认是否集中在少数 worker 上











