AWS下的WebSockets、SSL和回话保持服务
AWS 对于WebSockets、SSL 和 Sticky Sessions这三者的支持并不是很好,特别是ELB服务。可以得到客户端真实IP和粘性会话,但是不支持WebSockets。也可以支持 WebSockets但是获取不到客户端真实IP和粘性会话。这三者不能完美的融合在一起。下面来看下原因:
ELB可以作为反向代理和提供两种模式的负载均衡,TCP模式和HTTP模式,包含SSL。当前ELB不支持WebSockets的upgrade 协议,WebSocket 先是通过 HTTP 建立连接,然后通过 101 状态码, 表示切换协议,WebSocket 连接本质上是一个 TCP 连接。
ELB工作在HTTP模式下
这是最常见的配置,进行7层的代理转发,相当于nginx反代。
该架构优点:
- 可以通过X-Forward头部来获取客户端IP
- 回话粘性
- SSL
缺点:
- WebSockets不支持
- 不支持自定义协议,只有HTTP
由于会解析HTTP消息,因此可以注入特殊的头如X-Forward-IP来保留客户端IP和检查cookie以确保
回话粘性。而WebSockets是一种协议,以upgrade建立HTTP连接,因此必须需要实现upgrade机制,然而,ELB目前是不支持的。
ELB工作在TCP模式下
这时进行的4层转发。在TCP模式下,后端服务器可以获取客户端原始数据,这样就可以支持WebSockets,也可以处理HTTP请求了。
这种架构后端正常处理HTTP请求,因为ELB只是转发来自客户端的原始TCP流。
优点:
- 支持WebSockets
- 可以通过TCP使用附加协议
缺点:
- 没有回话粘性
- 获取不到客户端真实IP
- 应用程序需要更多的CPU进行SSL处理
这种情况下,不会有会话粘性,也没有X-Forward头,因为在这种模式下ELB没有解析HTTP消息,所以不可能匹配cookie,以确保会议粘性,也不会注入特殊的 X-Forward 头。
终极之战
最后绝招,需要的模块如下:
http://code.google.com/p/nginx-sticky-module
https://github.com/yaoweibin/nginx_tcp_proxy_module
当然,还有其它解决方案,如haproxy、hipache等等。
hipache: https://github.com/hipache/hipache
proxy protocol: http://www.haproxy.org/download/1.5/doc/proxy-protocol.txt