Nginx之websocket配置
在 Nginx 配置中,map $http_upgrade $connection_upgrade 主要用于 WebSocket 代理,以确保正确处理 Upgrade 头部,实现 WebSocket 连接。以下是完整的 Nginx 配置示例:
完整配置示例(WebSocket 代理)
http {
定义一个变量 $connection_upgrade
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name example.com;
location /ws/ {
proxy_pass http://backend_server;
proxy_http_version 1.1; # WebSocket 需要 HTTP/1.1
proxy_set_header Upgrade $http_upgrade; # 传递 Upgrade 头
proxy_set_header Connection $connection_upgrade; # 传递 Connection 头
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
参数解析
- map $http_upgrade $connection_upgrade
该指令将 Upgrade 头部映射到 Connection 头部:
如果 $http_upgrade 变量有值(比如 websocket),$connection_upgrade 设为 upgrade。
如果 $http_upgrade 为空,则设为 close。
- proxy_pass http://backend_server;
代理请求到后端 WebSocket 服务器。
- proxy_http_version 1.1;
WebSocket 需要 HTTP/1.1 支持,必须指定。
- proxy_set_header Upgrade $http_upgrade;
传递 Upgrade 头部,以保持 WebSocket 连接。
- proxy_set_header Connection $connection_upgrade;
传递 Connection 头部,确保 WebSocket 代理正确处理升级请求。
$http_upgrade 变量的值来自 HTTP 请求头中的 Upgrade 头部,它用于指示客户端希望升级的协议类型。常见的值包括:
-
WebSocket 连接
当浏览器或客户端请求 WebSocket 连接时,HTTP 请求头通常包含:
Upgrade: websocket
Connection: Upgrade此时,在 Nginx 配置中,$http_upgrade 变量的值为:
websocket
在 Nginx 配置中:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}这里的 '' close; 并不是直接关闭连接的意思,而是设置 Connection 头的值为 "close",告诉客户端和服务器在当前请求处理完成后不要保持连接。
含义解析
当 $http_upgrade 为空(即请求没有 Upgrade 头):
proxy_set_header Connection $connection_upgrade;这相当于:
proxy_set_header Connection "close";
这意味着 Nginx 会在响应后关闭连接(不复用 HTTP 连接),但不会主动断开连接或拒绝请求。
当 $http_upgrade 有值(如 websocket):
proxy_set_header Connection "upgrade";这允许 HTTP 连接升级到 WebSocket 等协议。
普通 HTTP 请求的情况
如果是普通的 HTTP 请求(如浏览器访问网页),通常不会包含 Upgrade 头部,因此:
$http_upgrade 为空('')
$connection_upgrade 设为 "close"
服务器会处理 HTTP 请求并正常返回响应
但 Nginx 会在响应后关闭连接,而不会保持 Keep-Alive 连接
是否会影响普通 HTTP 请求?
不会影响 HTTP 请求的正常处理,普通 HTTP 请求仍然会被 Nginx 正常响应。唯一的区别是:
Connection: close → 响应后关闭连接
Connection: keep-alive → 响应后保持连接(若启用 keepalive)
如果你希望在普通 HTTP 请求中也保持连接,可以修改 map 规则:
map $http_upgrade $connection_upgrade {
default upgrade;
'' keep-alive;
}
这样,普通 HTTP 请求的 Connection 头就会被设为 keep-alive,从而避免每次请求都重新建立 TCP 连接,提高性能。
总结
-
Connection: close 不会直接关闭连接,而是响应后不复用连接。
map 语句不会影响请求的正常处理,只是修改 Connection 头的行为。
可以改成 keep-alive,让普通 HTTP 请求保持连接,提高性能。
WebSocket 本身就是一种长连接。它与传统的 HTTP 连接不同,允许服务器和客户端之间进行全双工通信,而不需要客户端频繁发送请求来保持连接。
- WebSocket 为什么是长连接?
WebSocket 连接的生命周期如下:
- 客户端发起 WebSocket 握手
通过 HTTP/1.1 的 Upgrade 头进行协议升级:
GET /ws HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
服务器响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
连接升级后,通信协议从 HTTP 切换为 WebSocket。- 保持连接
连接建立后,WebSocket 不会像普通 HTTP 请求一样在响应后立即关闭。
服务器和客户端可以相互发送消息,并且消息可以是双向的(全双工通信)。
连接会一直保持,直到客户端或服务器主动关闭。
- 连接关闭
WebSocket 连接可以在任意一方调用 close() 方法后关闭:
客户端主动关闭 (ws.close())
服务器主动关闭
连接超时、网络异常等
- WebSocket vs. HTTP 连接
HTTP(短连接)
WebSocket(长连接)
通信方式
请求-响应模式(客户端发请求,服务器返回数据)
双向通信(客户端和服务器都能主动发送消息)
连接状态
一次请求完成后通常关闭连接
连接保持直到显式关闭
延迟
需要每次建立 TCP 连接
一次握手后持续使用,低延迟
适用场景
普通网页访问、API 请求
实时聊天、gupiao行情、在线游戏等
- WebSocket 是否需要 Connection: keep-alive?
不需要!
HTTP 的 keep-alive 主要用于 复用 TCP 连接,减少每次请求的握手开销。
WebSocket 连接建立后,本身就是 持久连接,不需要 keep-alive。
WebSocket 协议升级后,HTTP 头部(如 keep-alive)不再适用。
- WebSocket 代理中的 map 规则
在 Nginx 配置 WebSocket 代理时,通常使用:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}这里:
WebSocket 连接的 Upgrade: websocket 头部会使 Connection: upgrade,保持 WebSocket 连接。
普通 HTTP 请求没有 Upgrade 头,因此 Connection: close,表示请求完成后关闭连接(短连接)。
WebSocket 不依赖 keep-alive,它是天然的长连接。
- 什么时候 WebSocket 可能会断开?
尽管 WebSocket 是长连接,但以下情况可能导致断开:
- 服务器或客户端主动关闭
服务器调用 ws.close()
客户端调用 websocket.close()
- 网络异常
断网、超时、IP 变更等
- 代理/防火墙干预
一些代理服务器或防火墙可能会在一段时间内关闭空闲 WebSocket 连接。
解决方案:
心跳机制:定期发送 ping 数据包
设置 Nginx proxy_read_timeout:
location /ws/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s; # 避免超时
}
总结
✅ WebSocket 本质上是长连接,在连接建立后可以持续通信,直到主动关闭或发生网络问题。✅ 不需要 keep-alive,因为 WebSocket 连接本身就是持久的。✅ 需要处理可能的网络断开、代理超时等情况,以确保连接稳定。
你是遇到 WebSocket 连接被断开的情况,还是想优化 WebSocket 代理?
nginx 这些配置参数是否会影响websocket的长连接?
keepalive_timeout 65 ;
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
是的,这些 Nginx 配置参数会影响 WebSocket 长连接的稳定性,具体影响如下:
- keepalive_timeout 65;
作用:
适用于 HTTP 连接,控制客户端空闲连接在关闭前的最大等待时间(秒)。
如果客户端在 keepalive_timeout 时间内没有新请求,Nginx 关闭该连接。
对 WebSocket 的影响:
WebSocket 连接不受 keepalive_timeout 影响,因为 WebSocket 是升级后的持久连接,而 keepalive_timeout 仅影响 HTTP keep-alive 连接。
无影响,但如果你的 WebSocket 应用有 HTTP 轮询(long polling),该参数可能会影响 HTTP 连接的持久性。
✅ 结论:对 WebSocket 无影响,主要影响普通 HTTP 长连接。
- proxy_connect_timeout 300;
作用:
控制 Nginx 连接到后端服务器的超时时间(单位:秒)。
如果在 proxy_connect_timeout 时间内无法建立 TCP 连接(比如后端服务器响应慢),Nginx 将返回错误。
对 WebSocket 的影响:
仅影响 WebSocket 连接的初始建立阶段(握手阶段)。
不会影响已建立的 WebSocket 连接。
适用于后端服务器延迟较高的情况(如 WebSocket 服务器启动较慢)。
✅ 结论:仅影响 WebSocket 连接建立,不影响已建立的长连接。
- proxy_send_timeout 300;
作用:
控制 Nginx 向后端服务器发送数据的超时时间(单位:秒)。
如果 Nginx 在 proxy_send_timeout 时间内未能成功向后端发送完整的数据包,则连接会被关闭。
对 WebSocket 的影响:
WebSocket 服务器通常需要持续发送数据,如果 300 秒内没有任何数据发送,Nginx 可能会关闭 WebSocket 连接。
适用于控制长时间无数据发送的 WebSocket 连接,但通常 WebSocket 服务器会发送心跳包避免超时。
⚠️ 建议修改:如果 WebSocket 连接需要长时间保持,增大 proxy_send_timeout,比如:
proxy_send_timeout 3600s; # 1小时
✅ 结论:影响 WebSocket 长时间无数据发送的情况,建议增加超时时间或实现心跳机制。
- proxy_read_timeout 300;
作用:
控制 Nginx 从后端服务器读取数据的超时时间(单位:秒)。
如果 Nginx 在 proxy_read_timeout 时间内未能收到来自后端的任何数据,Nginx 会关闭连接。
对 WebSocket 的影响:
如果 WebSocket 连接在 300 秒内没有收到任何消息,Nginx 可能会断开连接。
适用于 WebSocket 服务器的长时间无数据传输的情况。
解决方法:
增加超时时间,比如:
proxy_read_timeout 3600s; # 1小时
使用 WebSocket 心跳(ping/pong),让服务器定期发送 ping,确保连接保持活跃。
⚠️ 建议修改:如果 WebSocket 需要长期连接,建议增大 proxy_read_timeout,避免意外断开。
✅ 结论:影响 WebSocket 长时间无数据接收的情况,建议增加超时时间或使用心跳包。
最佳 WebSocket 配置(优化长连接)
server {
listen 80;
server_name example.com;
location /ws/ {
proxy_pass http://backend_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_connect_timeout 10s; # 连接后端服务器超时
proxy_send_timeout 3600s; # 发送数据超时
proxy_read_timeout 3600s; # 读取数据超时
send_timeout 3600s; # 发送超时(客户端)
}
}
总结
参数
默认值
作用
对 WebSocket 的影响
优化建议
keepalive_timeout
65s
控制 HTTP keep-alive 连接超时
无影响
无须更改
proxy_connect_timeout
60s
连接后端 WebSocket 服务器超时
仅影响连接建立
可调小,如 10s
proxy_send_timeout
60s
向后端发送数据超时
影响长时间无数据发送
增大,如 3600s
proxy_read_timeout
60s
从后端读取数据超时
影响长时间无数据接收
增大,如 3600s
???? 重点优化:
proxy_read_timeout 和 proxy_send_timeout 需要足够大,防止 WebSocket 连接因超时断开。
WebSocket 服务器定期发送心跳包(ping/pong),保证连接存活。
keepalive_timeout 不影响 WebSocket,可忽略。