
本文作者银河技术,有修订和改动。
WebSocket 是基于 HTTP/1.1 Upgrade 机制实现的全双工长连接通信协议,广泛应用于 IM即时通讯、实时通知、协同编辑、行情推送、游戏服务等场景。
由于 WebSocket 是长连接 + 状态敏感的协议,在 Nginx 中做反向代理时,需要特别注意一些细节。
这些细节主要是:
本文从基础配置、生产配置、Docker / K8s、安全、排障、性能调优,系统性讲清 WebSocket 在 Nginx 中的正确打开方式。


WebSocket 通过 HTTP/1.1 完成握手:
GET /ws HTTP/1.1 Upgrade: websocket Connection: Upgrade
一旦升级成功,连接将不再遵循 HTTP 请求-响应模型,而是长期保持的双向 TCP 通道。
PS:这也是为什么 WebSocket 对 Nginx 超时 / FD / 内核参数 / LB 极度敏感。
更多WebSocket基础资料可以继续阅读:

http { # 基础 WebSocket 代理配置 upstream websocket_backend { server 192.168.1.100:8080; server 192.168.1.101:8080; # 支持长连接 keepalive 10; } server { listen 80; server_name ws.example.com; location /ws/ { # 核心 WebSocket 配置 proxy_pass http://websocket_backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 重要:传递原始主机头和客户端 IP proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 长连接超时设置 proxy_read_timeout 3600s; proxy_send_timeout 3600s; proxy_connect_timeout 30s; # 禁用缓冲,确保实时性 proxy_buffering off; proxy_cache off; } } }
补充说明:
注意:这是原始配置中最容易踩坑、但极其重要的一点。
推荐写法:
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
然后在 location 中:
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade;
为什么这样更安全?
PS:避免普通 HTTP 请求被错误升级。
http { upstream websocket_cluster { ip_hash; server 10.0.1.10:8080 weight=3; server 10.0.1.11:8080 weight=2; server 10.0.1.12:8080 backup; # 以下健康检查依赖 nginx_upstream_check_module(非官方) check interval=3000 rise=2 fall=3 timeout=1000 type=http; check_http_send "GET /health HTTP/1.0\r\n\r\n"; check_http_expect_alive http_2xx http_3xx; } server { listen 443 ssl http2; server_name ws.example.com; ssl_certificate /etc/nginx/ssl/example.com.crt; ssl_certificate_key /etc/nginx/ssl/example.com.key; ssl_protocols TLSv1.2 TLSv1.3; location /chat/ { proxy_pass http://websocket_cluster; # WebSocket 升级 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # 原始请求信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # ⚠️ 长连接超时 proxy_read_timeout 86400s; proxy_send_timeout 86400s; # 实时性 proxy_buffering off; # 连接限制 limit_conn ws_conn 1000; } } } limit_conn_zone $binary_remote_addr zone=ws_conn:10m;
基本配置:
listen 443 ssl http2;
重要认知:
PS:这是正常现象,不是配置错误。
WebSocket location 必须显式:
proxy_http_version 1.1;

map $http_upgrade $connection_upgrade { default upgrade; '' close; } server { listen 80; location /ws/ { proxy_pass http://websocket-service:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_read_timeout 7d; proxy_send_timeout 7d; proxy_buffering off; } }
K8s / 云环境的隐藏断连点:

PS:Nginx 再怎么配都没用,必须应用层心跳
推荐 20~30 秒一次:
{ "type": "ping" }
否则云 LB、防火墙、NAT,都会主动断你连接。

upstream websocket_backend { ip_hash; server 10.0.1.10:8080; server 10.0.1.11:8080; }
实战建议:

PS:WebSocket 本质上 不适合强依赖 LB 算法做会话保持
K8s 必配:
terminationGracePeriodSeconds: 60
后端逻辑:

Nginx配置如下:
worker_processes auto; worker_rlimit_nofile 200000; events { worker_connections 65535; use epoll; }
Linux操作系统的配置:
net.core.somaxconn = 65535 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_fin_timeout = 15
指令如下:
wscat -c ws://domain/ws ss -an | grep ESTAB | wc -l
[1] RFC6455 协议文档、WebSocket API文档、SSE API文档
[2] 新手入门贴:史上最全Web端即时通讯技术原理详解
[3] Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
[4] 详解Web端通信方式的演进:从Ajax、JSONP 到 SSE、Websocket
[5] 网页端IM通信技术快速入门:短轮询、长轮询、SSE、WebSocket
[6] 搞懂现代Web端即时通讯技术一文就够:WebSocket、socket.io、SSE
[7] WebSocket详解(四):刨根问底HTTP与WebSocket的关系(上篇)
[8] WebSocket详解(六):刨根问底WebSocket与Socket的关系
[9] Web端即时通讯实践干货:如何让你的WebSocket断网重连更快速?
[10] WebSocket从入门到精通,半小时就够!
[11] 理论联系实际:从零理解WebSocket的通信原理、协议格式、安全性
[12] 浅谈网页端IM技术及相关测试方法实践(包括WebSocket性能测试)》
[13] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗
[14] 零基础IM开发入门(一):什么是IM系统?
[15] 转转客服IM系统的WebSocket集群架构设计和部署方案
[16] 基于WebSocket的IM即时通信方案在H5游戏场景下的技术实践
[17] 详解AI大模型实时通信为什么选SSE,而不是WebSocket和WebRTC
[18] 都HTML5了,Web端即时通讯技术到底该用什么?一文即懂!
(本文同步发布于: http://www.52im.net/thread-4921-1-1.html)
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。