P75 什么是 WebSocket?Nginx 如何支持 WebSocket 协议?
面试题:WebSocket 是什么?和 HTTP 什么关系?Nginx 怎么配置支持 WebSocket?
1. WebSocket 是什么
WebSocket 是一种全双工通信协议,基于 TCP:
- 客户端和服务端建立连接后,双方可以随时主动发消息(服务器主动推送);
- 一次握手后长连接,不用像 HTTP 那样反复建立连接;
- 适用:聊天、实时通知、直播间弹幕/大屏、在线协作。
与 HTTP 的关系:
- WebSocket 握手复用 HTTP 协议(101 Switching Protocols 升级);
- 握手头:
Upgrade: websocket、Connection: Upgrade、Sec-WebSocket-Key; - 握手成功后切换到 WebSocket 帧协议,不再是 HTTP 语义。
2. WebSocket vs HTTP
| 对比项 | HTTP | WebSocket |
|---|---|---|
| 通信方向 | 请求-响应(客户端发起) | 双向,服务端可主动推送 |
| 连接 | 短连接(或 keep-alive 复用) | 长连接(全双工) |
| 消息 | 文本/二进制,带完整头 | 帧,开销小 |
| 适用 | 常规接口 | 实时场景 |
3. Nginx 如何支持 WebSocket
默认 Nginx 对 HTTP 是"请求-响应"代理,WebSocket 需要协议升级 + 长连接保持:
nginx
location /ws/ {
proxy_pass http://websocket-backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # 透传 Upgrade 头
proxy_set_header Connection "upgrade"; # 关键:告诉后端这是升级连接
proxy_set_header Host $host;
proxy_read_timeout 3600s; # 长连接超时,不能太小
proxy_send_timeout 3600s;
}关键点:
Upgrade和Connection: upgrade两个头必须透传,否则握手失败;proxy_read_timeout要调大(如 1 小时),否则空闲连接被 Nginx 掐断;- 支持 WSS:443 端口配 SSL,Nginx 做 TLS 终止,再转发到后端 WebSocket。
4. 加分点
- 提到连接数管理:WebSocket 是长连接,占用 fd/内存,Nginx worker_connections 要评估;
- 提到心跳/重连:客户端断线重连、服务端心跳保活;
- 集群部署时 WebSocket 连接粘性(sticky session)问题:广播/推送需要路由到正确的节点(Redis Pub/Sub 或 MQ 广播)。
一句话总结
WebSocket 是复用 HTTP 握手的全双工长连接协议,服务端可主动推送;Nginx 支持它要透传 Upgrade/Connection: upgrade 头、调大读写超时,并考虑长连接的连接数、心跳与集群路由。