websocket限速需分层协同:握手阶段用limit_req限频,连接数用limit_conn限制,并配合limit_rate控带宽、proxy_buffering off降延迟,且必须设置upgrade/connection头部以避免403错误。

WebSocket 是长连接,Nginx 无法像 HTTP 短连接那样直接对帧级流量做每秒请求数(QPS)限速,但可通过多层协同实现真正有效的多维度限速:覆盖握手阶段、连接数量、传输带宽及后端调用行为。关键在于分层控制,不依赖单一机制。
限制 WebSocket 握手频率(防重连风暴)
客户端建立 WebSocket 连接前,必须发送一次标准 HTTP GET 握手请求(含 Upgrade: websocket)。这部分属于普通 HTTP 请求,可直接用 limit_req 控制:
- 在
http块中定义按 IP 限速的区域,例如每分钟最多 10 次握手:limit_req_zone $binary_remote_addr zone=ws_handshake:10m rate=10r/m; - 在对应
location /ws/中启用,并允许少量突发(如重试):limit_req zone=ws_handshake burst=5 nodelay; - 该配置能有效拦截高频重连、恶意扫描或未正确处理断线重连逻辑的客户端。
控制并发长连接数(防资源耗尽)
单个 IP 建立过多 WebSocket 连接会迅速占满 Nginx 工作进程的文件描述符和内存。使用 limit_conn 限制并发连接总数:
- 定义连接限制区域:
limit_conn_zone $binary_remote_addr zone=ws_conn:10m; - 在 location 中设置上限(如每个 IP 最多 8 个活跃连接):
limit_conn ws_conn 8; - 建议配合
limit_conn_log_level warn和limit_conn_status 503,便于识别拒绝原因并记录日志。
约束单连接带宽与响应延迟(保实时性)
对消息密集型场景(如行情推送、协作编辑),需防止单个连接持续大流量输出拖慢整体代理性能:
- 启用
limit_rate限制单连接响应速率,例如限制为 256KB/s:limit_rate 262144; - 关闭缓冲降低端到端延迟:
proxy_buffering off; - 延长超时避免误断连:
proxy_read_timeout 3600;和proxy_send_timeout 3600;(单位秒,应大于业务心跳周期)
补充:确保代理头完整,避免 403 握手失败
若缺少关键头部,Nginx 会拒绝升级请求并返回 403。以下三行必须同时存在:
proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
缺一不可。其中 $http_upgrade 变量自动透传客户端原始 Upgrade 头,不可硬编码为字符串。











