ALB后端Elastic Beanstalk部署的WSS连接404升级失败求助
我之前在AWS上部署Rails Action Cable(看你的/cable路径应该是这个场景)的时候,也碰到过一模一样的WebSocket 404握手失败问题,折腾了好几天才搞定,给你分享几个最可能的排查方向和解决办法:
1. 先检查ALB的核心配置
ALB虽然默认支持WebSocket,但如果配置不对,握手请求根本到不了后端的Beanstalk实例:
- 先确认ALB的HTTPS监听器规则:确保
/cable和/cable/这两个路径都能正确转发到你的Beanstalk目标组,别漏了带斜杠的情况(从你的日志看有这个请求) - 检查目标组的健康状态:如果目标组里的Beanstalk实例健康检查失败,ALB会直接返回404,所以先确保健康检查路径(比如
/health或者你的应用根路径)能正常返回200 - 别忽略WAF或头过滤:如果你的ALB挂了WAF,或者有自定义的头过滤规则,要确保没把
Upgrade和Connection这两个WebSocket握手必备的请求头给拦截或删除了
2. 修复Beanstalk的Nginx配置(关键!)
Beanstalk默认的Nginx配置不会正确处理WebSocket的升级请求,必须手动修改:
在你的项目根目录创建.ebextensions文件夹,然后新建一个01-websocket-support.config文件,内容如下:
files: "/etc/nginx/conf.d/websocket.conf": mode: "000644" owner: root group: root content: | # 处理不带斜杠的/cable请求 location /cable { proxy_pass http://app_server; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header 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 86400; # 给WebSocket长连接设置足够长的超时 } # 把带斜杠的/cable/重定向到/cable,避免路由不匹配 location = /cable/ { return 301 /cable; }
把这个配置提交到代码仓库,重新部署到Beanstalk,Nginx会自动加载这个配置,处理WebSocket的升级请求。
3. 验证应用端的路由匹配
从你的日志看有Started GET "/cable/"的请求,而你客户端用的是/cable(不带斜杠):
- 如果是Rails项目,确保
routes.rb里的Action Cable路由是mount ActionCable.server => '/cable'(不要带斜杠) - 要是你的框架路由是严格匹配的,带斜杠的
/cable/就会触发404,这也是为什么我们在Nginx里加了重定向的原因
4. 用curl手动测试握手
可以用curl模拟WebSocket握手请求,快速定位问题:
curl -i -H "Upgrade: websocket" -H "Connection: upgrade" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" -H "Sec-WebSocket-Version: 13" https://example.com/cable
- 如果返回
101 Switching Protocols,说明握手流程没问题,问题可能在客户端代码 - 如果还是返回404,说明请求没到应用,回头检查ALB和Nginx的配置
5. 最后检查安全组和网络ACL
别忽略最基础的网络配置:
- ALB的安全组要允许443端口的入站流量
- Beanstalk实例的安全组要允许ALB的安全组访问80/443端口
- 对应的VPC网络ACL也要允许相关的进出流量
按照这个顺序排查,应该能解决你的404问题,我当时就是卡在Nginx的配置上,加上WebSocket支持后就正常了。
内容的提问来源于stack exchange,提问作者waynep
相关产品推荐
相关产品推荐

