socket.io是目前较为流行的web实时推送框架,其基于nodejs语言开发,底层用engine.io实现。 借助nodejs语言异步的特性,其获得了不错的性能。但单个实例的socket.io依然承载能力有限,最多只能容纳3000个long-polling方式的客户端进行连接。      将socket.io进行分布式扩展的难点有两处: 1. **进行负载均衡时客户端**必须保证始终连到一个节点上 如果客户端采用long-polling长轮训方式进行连接,则每次轮训都会产生一个新的请求,若不进行限制。就有可能连接到集群内新的 socket.io节点上,导致异常的发生。 **     解决方法:** 使用nginx的ip\_hash实现session sticky ,让客户端始终连接到集群内一台节点上。 2. **多个实例之间的消息推送** 当集群内某台节点想要向连接到集群的所有客户端发送消息时,某些客户端因为负载均衡时ip\_hash可能被分配到了其他的节点上,这时就需要向其他节点发布推送消息,让其他节点的同时向客户端进行推送。     **解决方法:**使用redis的发布与订阅功能与[socket.io-redis开源库](https://github.com/Automattic/socket.io-redis),该库在节点向客户端群发消息时会将该消息发布到redis的订阅队列中,让其他节点能够订阅到该消息,从而实现节点间消息推送。 ![](https://img.kancloud.cn/db/47/db478bed672bd8f9b34cbad9459b4ed2_774x549.png) 上图是采用该架构的一个聊天服务器集群示例,每个chatnode相当于一个socket.io实例,其中的chatModule负责客户端连接,adminModule负责聊天服务器的管理功能。        adminnode作为整个集群的管理节点,通过redis的消息订阅功能来与各个chatnode通信, 并通过开放http接口来与外部系统进行交互。