+86 13541016684Mon. - Fri. 10:00-22:00

配置AWS ELB支持Websocket和Stickiness

AWS ELB支持Websocket和Stickiness

配置AWS ELB支持Websocket和Stickiness

场景

某项目部署在AWS上,使用AWS的 ELB 以及多个EC2 instance。

  • 需要支持HTTP(s) stickiness
  • 项目中使用了websocket (没有stickiness需求)
  • 只有ELB向外开放了访问权限

问题

AWS ELB 目前只支持HTTP(s)和TCP(SSL),并不支持websocket使用的ws(s)。HTTP(s)是Application Layer的,TCP(SSL)是Transport Layer的,而ws(s)也是Application Layer的。因为ELB不支持ws(s),如果要支持websocket,必须使用TCP(SSL)协议来支持ws(s),可以参考这篇官方论坛文章

解决方案

我们只需要在ELB中设置两个协议,一个为HTTP(s),另一个为TCP(SSL),其中TCP的配置是为了websocket。因为不能使用同一个端口,因此在ELB上HTTP(s)端口使用80(443),而TCP(SSL)则需要使用另外一个端口。
另外,在我们的项目代码中,需要将websocket的端口改为此处设置的TCP(SSL)端口,示例中为5555。

124

ELB 配置

解决开发中的问题

为了在release中支持ELB,我们项目代码中做出相应端口的修改。这给开发带来了一个小问题,开发环境中并没有用到ELB,开发人员一般用同 一个端口同时相应HTTP(s)和ws(s),因此如果直接在代码中硬编码端口,则会给开发带来麻烦。我们的解决方法是添加配置文件,然而配置文件只有在 release环境中才会启用。

应用限制

通过上述方案,基本解决了HTTP(s) stickiness和websocket在ELB中并存的问题,然而这种解决方案并不支持websocket的stickiness,因此需要在开发中 额外解决。当然,使用HTTP(s) stickiness并不见得是好的方式。

参考文章

http://stackoverflow.com/questions/15266702/proxying-websockets-with-tcp-load-balancer-without-sticky-sessions
https://medium.com/@Philmod/load-balancing-websockets-on-ec2-1da94584a5e9
http://www.raweng.com/blog/2014/11/11/websockets-on-aws-elb/
http://johan.heapsource.com/post/31047804966/the-state-of-websockets-ssl-and-sticky-sessions