SSE (Server-Sent Events) 服务出现连接卡在 pending 状态的原因
SSE (Server-Sent Events) 和 WebSocket (WSS) 服务出现连接卡在 pending 状态的原因,主要与 Nginx 的 缓冲机制 和 代理行为 有关
1. Nginx 默认的 proxy_buffering on
如何影响 SSE/WSS
Nginx 默认开启 proxy_buffering on
,其行为如下:
缓冲响应数据:Nginx 会先完整接收上游服务器(如
http://172.18.117.82:31609
)的响应,再转发给客户端。分块传输禁用:对于流式协议(如 SSE/WSS),缓冲会强制等待响应完成,破坏了实时性。
对 SSE 的影响
SSE 依赖 长连接 和 流式传输,需要数据实时到达客户端。
如果 Nginx 开启缓冲,会等待上游服务的数据积累到一定量(或超时)后才发送,导致客户端长时间处于
pending
状态。
对 WebSocket (WSS) 的影响
WebSocket 是双向全双工协议,需要 即时传输。
缓冲可能导致握手响应被延迟,连接无法正确升级(
Upgrade: websocket
)。
2. 为什么 proxy_buffering off;
能解决问题?
关闭缓冲后:
数据实时透传:Nginx 会立即将上游服务器的数据转发给客户端,不等待缓冲填满。
支持流式传输:SSE 的事件流和 WebSocket 的帧可以即时到达客户端。
保持长连接活跃:避免因缓冲超时中断连接。
3. 总结
配置项 | 默认值 | 对 SSE/WSS 的影响 | 推荐值 |
---|---|---|---|
proxy_buffering | on | 缓冲导致数据延迟,连接卡在 pending | off |
proxy_cache | 视全局配置 | 缓存会破坏实时性 | off |
proxy_read_timeout | 60s | 短超时会中断长连接 | 86400s |
Upgrade 头 | 无 | WebSocket 必需 | 显式设置 |
根本原因:
Nginx 的默认缓冲行为与流式协议(SSE/WSS)的实时性要求冲突,导致数据被延迟发送,表现为 pending
。通过 proxy_buffering off
禁用缓冲即可解决。
对于 Server-Sent Events (SSE) 服务,除了设置 proxy_buffering off;
外,强烈建议同时设置 proxy_cache off;
,以确保 SSE 的事件流能实时、正确地传输到客户端。
SSE 是长连接、实时流式协议
SSE 依赖 HTTP 长连接,持续推送事件(
text/event-stream
)。如果 Nginx 启用缓存(
proxy_cache on
),可能会错误地缓存流式响应,导致客户端收不到新事件。
Nginx 默认缓存行为的影响
即使没有显式配置
proxy_cache
,Nginx 仍可能因全局缓存设置或proxy_cache
默认值影响 SSE。缓存会导致:
事件延迟:客户端可能收到旧数据。
连接中断:缓存机制可能提前关闭连接。
proxy_buffering off
不足以保证实时性proxy_buffering off
确保数据不缓冲,但proxy_cache on
仍可能导致响应被缓存。