本质是Nginx代理越权处理WebSocket流量,优化核心是回归透传本职:禁用压缩与缓冲、关闭日志、设紧致超时、限制连接池与建连频次、统一buffer尺寸并调优系统资源。

WebSocket 代理内存过高,本质不是“连接多”,而是 Nginx 在转发过程中做了不该做的事——缓存帧、压缩上下文、维持冗余连接、反复分配小内存块。优化核心是让代理回归本职:干净透传,不存状态,不干预协议。
精简代理职责,禁用所有非透传功能
WebSocket 流量不需要 HTTP 那套处理逻辑,任何额外动作都会吃内存:
- 显式关闭压缩:
proxy_set_header Sec-WebSocket-Extensions "",防止 Nginx 缓存 permessage-deflate 上下文 - 彻底禁用缓冲:
proxy_buffering off;,再加proxy_buffer_size 0; proxy_buffers 8 0;,避免内部 buffer 积累 - 不解析、不分组、不鉴权:所有
/ws/路径统一透传,URL path 和 query 参数由后端处理,Nginx 不做重写或条件判断 - 关闭日志:
access_log off; error_log /dev/null warn;,消除高频字符串拼接和 I/O 分配开销
控制连接生命周期,拒绝无效连接滞留
大量空闲但未关闭的连接会持续占用 socket 和内存结构,必须主动管理:
- 设紧致超时:
proxy_read_timeout 60;(握手+空闲总时长上限),proxy_send_timeout 10;(防发心跳卡住) - 限制上游连接池:
upstream backend { keepalive 32; },避免每个客户端独占后端连接 - 前置限频:
limit_req zone=ws_conn burst=5 nodelay;,按 IP 限制建连频率(如 5 次/分钟),过滤爬虫或异常重连 - 确保后端返回
Connection: keep-alive,而非close,否则 keepalive 机制失效
优化底层内存分配,减少碎片堆积
Nginx worker 进程频繁分配小 buffer 是内存上涨主因,需固定尺寸、限制增长:
- 统一 buffer 大小:
proxy_buffer_size 4k; proxy_buffers 8 4k;,避免动态扩容导致堆碎片 - 提升初始堆容量:启动时加
-g "worker_rlimit_core 2G;"并指定working_directory /var/tmp/,便于后续分析 - 调大系统级文件描述符:
* soft nofile 1048576和* hard nofile 1048576写入/etc/security/limits.conf - 内核参数协同:
net.core.somaxconn = 65535,net.ipv4.tcp_tw_reuse = 1,net.ipv4.ip_local_port_range = 1024 65535
分层监控与快速定位泄漏点
别只看 RSS 总值,要盯住真实内存健康度:
- 定期执行
pmap -x $(pgrep nginx | head -n1) | tail -n 10,观察 mmap 区域是否异常增长 - 用
pstack <pid>查 worker 是否卡在SSL_read或epoll_wait,确认是否 TLS 握手阻塞 - 检查共享内存:
ipcs -m | grep nginx,确认无未清理的 shm 段 - Prometheus + nginx-vts-exporter 监控每 worker 的连接数、活跃连接、buffer 使用率


















