核心思路是将连接管理与业务处理彻底分离,代理层仅轻量转发、禁用鉴权/压缩/广播等非必要功能;关闭permessage-deflate、proxy_buffering,设严格超时(proxy_read_timeout 60; proxy_send_timeout 10;),启用keepalive限制与ip限频,并优化底层内存分配及监控。

核心思路是把“连接管理”和“业务处理”彻底分开,让代理层只做轻量转发,不碰业务逻辑、不存状态、不参与序列化压缩。
精简代理层职责,禁用一切非必要功能
WebSocket 代理(如 Nginx、Envoy 或自研网关)不是应用服务器,不该承担鉴权、消息解析、压缩、广播等任务:
- 关闭
permessage-deflate:Nginx 默认不启用,但若后端启用了而代理透传该 header,会导致代理内部缓存压缩上下文。在 proxy 配置中显式清除:proxy_set_header Sec-WebSocket-Extensions "" - 禁用代理缓冲:避免 Nginx 缓存 WebSocket 帧,加配置
proxy_buffering off; proxy_buffer_size 0; proxy_buffers 8 0; - 跳过重写与路由逻辑:不解析 URL path 做分组或鉴权,所有 /ws/* 统一透传;业务路由由后端网关完成
控制连接生命周期,拒绝无效连接膨胀
内存上涨常源于“连接建了却不活”,代理需主动干预,而非被动转发:
- 设置严格超时:
proxy_read_timeout 60;(非默认 60 秒“等死”,而是握手+空闲总时长上限),配合proxy_send_timeout 10;防止发心跳卡住 - 启用连接复用限制:Nginx 的
keepalive 32;控制上游连接池大小,避免为每个客户端维持独占后端连接 - 前置 IP + User-Agent 限频:用
limit_req对高频建连行为限速(如 5 次/分钟/IP),过滤爬虫或异常重连客户端
优化底层资源分配,避免小块碎片堆积
代理进程本身(如 Nginx worker)的内存问题,多来自频繁分配小 buffer:
- 调大 worker 进程初始堆:Nginx 启动时加
-g "worker_rlimit_core 2G;"并配working_directory /var/tmp;,便于后续分析 core - 固定读写 buffer 大小:在 upstream 中设
proxy_buffer_size 4k; proxy_buffers 8 4k;,避免动态扩容导致碎片 - 关闭日志写入(生产环境):
access_log off; error_log /dev/null warn;,消除高频字符串拼接和 I/O 分配
分层监控与快速定位
不靠总内存看高低,而盯住代理进程的内存健康度:
- 定期采集
nginx -s status或 Prometheus 的nginx_connections_active+process_resident_memory_bytes - 用
pstack <pid></pid>查看 worker 是否卡在 SSL read/write —— 若大量线程停在SSL_read,说明 TLS 握手或证书校验阻塞,需切 ECDSA 证书或升级 OpenSSL - 对怀疑泄漏的 worker 执行
gcore <pid></pid>,再用gdb -p <pid> -ex "info proc mappings" -ex "quit"</pid>看 mmap 区域是否异常增长











