HAProxy 2.4 基于h2的WebSocket连接失败且未收到connect请求排查
问题解答
1. 为什么HAProxy没有收到connect请求?
你配置的443端口ALPN规则优先使用HTTP/2协议,而WebSocket over HTTP/2(RFC 8441规范)要求服务端主动返回SETTINGS_ENABLE_CONNECT_PROTOCOL设置帧宣告支持该扩展,HAProxy 2.4默认没有开启该配置。浏览器检测到当前HTTP/2连接不支持WebSocket所需的CONNECT协议扩展,会直接丢弃WebSocket、SSE的connect请求,根本不会将请求发送到HAProxy,因此日志中没有对应记录。
2. 为什么无法正常建立WebSocket连接?
除了上述请求未发出的问题外,你当前的HAProxy配置缺少WebSocket升级处理逻辑,即使请求到达HAProxy也无法正常完成代理转发:
- HAProxy默认不会自动识别WebSocket升级请求,不会主动转发
Upgrade、Connection头,也不会切换到隧道模式处理长连接 - 你配置的后端默认优先使用HTTP/2协议通信,部分服务端对代理转发的h2 WebSocket请求兼容性不佳
修复方案
按以下步骤修改你的HAProxy配置即可解决问题:
- 开启HTTP/2 CONNECT协议扩展支持,修改
www-httpsStrict前端的bind配置,同时新增WebSocket请求处理规则:
frontend www-httpsStrict bind *:443 tfo ssl crt /etc/ssl/private alpn h2,http/1.1 h2-settings enable-connect-protocol=1 option forwardfor option splice-auto # 新增WebSocket识别和处理规则 acl is_websocket hdr(Upgrade) -i websocket http-request set-header Connection upgrade if is_websocket http-request set-header Upgrade websocket if is_websocket acl test hdr_sub(cookie) istest=true use_backend test_backend if test default_backend www-backendStrict
- 如果需要兼容旧版浏览器,可将ALPN顺序调整为优先使用HTTP/1.1,WebSocket在HTTP/1.1协议下的兼容性更稳定:
# 将alpn参数调整为如下格式 bind *:443 tfo ssl crt /etc/ssl/private alpn http/1.1,h2 h2-settings enable-connect-protocol=1
- 你当前配置的
timeout tunnel 1h已经可以满足常规WebSocket长连接的超时需求,无需额外修改。
内容的提问来源于stack exchange,提问作者Cine
相关产品推荐
相关产品推荐

