我在AWS上设置了两个EC2实例,运行在负载均衡器后面,但是套接字。当两个实例同时运行时IO中断。我假设ELB在实例和Socket之间轮询。io在更新到Websockets之前发送请求,这会导致socket io中断(会话ID未知)。我认为,通过使用共享会话存储在Redis, Socket。IO可以工作,因为所有实例都可以访问会话。
我有一个小的应用程序开发在Node.js(更具体地说Sails.js)只是为了测试。我设法配置ELB在TCP模式下支持Websockets,将请求转发到运行Sails.js应用程序的(Phusion Passenger + NGINX)。
应用程序使用Redis运行在amazon Elasticache上的SESSIONS和SOCKETS。如果我在没有ELB的情况下单独测试两个实例,我看到Redis正在为Sockets工作,因为消息在两个实例中发送和接收。
是否共享会话足以创建Socket。io工作吗?或者我需要ELB中的粘性会话来将客户端转发到相同的实例?
我选择ELB,因为它更容易动态地添加和删除实例,这是复杂的NGINX(免费)或HAProxy。
任何想法?
当你在云中运行一个服务器,它有负载平衡器/反向代理,路由器等,你需要配置它正常工作,特别是当你扩展服务器使用多个实例。
约束之一套接字。io、SockJS和类似的库都有一个缺点,那就是它们需要不断地与服务器的同一个实例进行通信。当只有一个服务器实例时,它们可以很好地工作。
当你在云环境中扩展你的应用程序时,负载均衡器(在cloud Foundry的情况下是Nginx)将接管,请求将被发送到不同的实例,导致Socket。
为了在这种情况下提供帮助,负载均衡器有一个称为"粘性会话"的功能,又名"会话亲和性"。主要思想是,如果设置了此属性,那么在第一个负载均衡请求之后,所有以下请求将转到相同的服务器实例。
在Cloud Foundry中,基于cookie的粘性会话是为设置cookie jsessionid的应用程序启用的。
注意:jsessionid是通常用于跟踪Java/Spring应用程序会话的cookie名称。Cloud Foundry只是将其作为所有框架的会话cookie。
所以,所有应用程序需要做的就是设置一个名为jsessionid的cookie来制作套接字。io工作。
app.use (cookieParser);app.use(表达。session({store:sessionStore, key:'jsessionid', secret:'你的秘密在这里'}));
步骤如下:
- Express设置一个名为jsessionid的会话cookie。 当套接字
- 。io连接,它使用相同的cookie并点击负载均衡器
- 负载均衡器总是将它路由到设置cookie的同一台服务器。
- 如果您正在使用应用程序负载平衡器,则会话保持设置在目标组级别