如何让AWS负载均衡将同一路由的WebSocket请求转发至同一EC2实例?
问题:WebSocket动态路由的EC2实例粘性转发配置
需求说明
- 客户端通过
wss://example.com/ws/1234这类动态生成的WebSocket URL连接服务 - 同一路由(如
/ws/1234)的所有用户必须连接到同一EC2实例 - 首次访问某动态路由时,将请求路由到当前CPU负载最低的EC2实例
- 后续访问同一路由的客户端,必须转发到首次分配的实例
已尝试的操作
尝试配置EC2自动扩缩组的监听器规则,但未找到匹配需求的设置选项,尝试的配置截图如下:
解决方案
方案1:基于ALB的路径匹配+粘性会话实现
AWS Application Load Balancer(ALB)可以结合路径路由和粘性会话满足大部分需求:
- 配置ALB的HTTPS监听器(WebSocket依赖HTTP/HTTPS协议升级)
- 为EC2自动扩缩组创建目标组,开启应用级粘性会话,设置合适的会话超时时间(比如24小时,根据业务调整)
- 添加监听器规则:匹配路径模式
/ws/*,将请求转发到目标组 - 调整目标组的负载均衡算法为最小请求数(或结合CloudWatch指标自定义CPU负载导向的分配逻辑)
- 首次访问
/ws/xxx时,ALB会按算法分配负载最低的实例,粘性会话会将该路径的后续请求绑定到同一实例 - 注意:默认粘性基于Cookie,需要确保客户端保留Cookie;若无法依赖Cookie,可考虑自定义头部标识路由,但需要额外开发逻辑
- 首次访问
方案2:自定义路由映射服务
如果ALB原生功能无法满足精准的动态路由粘性,需要自行实现路由逻辑:
- 搭建轻量路由服务(Node.js/Go均可),维护
动态路由 -> EC2实例ID的映射表(用Redis等缓存存储) - 客户端请求先打到路由服务,首次访问
/ws/xxx时,路由服务通过CloudWatch API获取EC2实例的CPU负载数据,选择负载最低的实例,将映射关系存入缓存 - 后续同一路由的请求,直接从缓存读取实例地址并转发
- 监听EC2自动扩缩组的实例状态变更,当实例被终止时自动清理对应映射,后续请求重新分配新实例
内容的提问来源于stack exchange,提问作者Alexei Snytkine
相关产品推荐
相关产品推荐

