Socket.io 分布在不同的服务器上
Posted
技术标签:
【中文标题】Socket.io 分布在不同的服务器上【英文标题】:Socket.io distribute across different servers 【发布时间】:2015-04-16 09:21:28 【问题描述】:我想在 3 台不同的机器上设置 socket.io 服务器。我有一个负载平衡器设置,用于在不同的服务器之间分配请求,但是如何将我在 socket.io 的连接函数中获得的套接字对象分配到不同的服务器?我知道我们可以使用 RedisStore pub/sub 来发布和写入 redis 事件,但假设我有一个连接到机器 1 的客户端 A,如果我有一个连接到机器 3 的客户端 B。客户端 A 将如何发送给客户 B 的消息?或者我可以使用 socket.io 中的其他架构来实现这一点?
【问题讨论】:
您不能将套接字对象分发到不同的服务器。套接字对象属于特定的网卡,并且只能与该网卡一起使用。您可以让您的服务器相互通信,以便与连接到另一台服务器的客户端通信。通常使用单个共享 redis 存储来跟踪给定客户端连接到哪个服务器。 谢谢您,您知道是否有任何其他技术堆栈可以让我们这样做? 你可以在这里阅读:socket.io/docs/using-multiple-nodes 是的,但这会在同一个盒子上设置不同的 socket.io 线程,对吧? 那篇文章的开头说:“如果您打算在不同的进程或机器之间分配连接负载”。后来它指的是:“在进程或计算机之间传递消息”。 【参考方案1】:正如 cmets 中提到的,套接字是两台不同机器(本例中为客户端和服务器)之间的连接,因此不能共享。对于解决此问题的基本结构,您需要 3 个组件:负载均衡器、套接字服务器和消息传递系统(Redis、RabbitMQ 等)
负载均衡器
最外层是负载均衡器。并非所有浏览器都支持 Web 套接字,因此 Web 套接字库提供 HTTP 轮询故障转移。本质上,客户端通过 HTTP 发起握手,服务器尝试将您的连接升级到构建在直接 TCP 之上的双向二进制协议。如果成功,您将通过 Web 套接字与服务器建立一对一的连接。如果失败,套接字库将通过 HTTP 处理请求,并通过轮询来模拟 Web 套接字。
因此,您的负载平衡器必须配置为确保客户端的所有请求都发送到同一台服务器,否则多个服务器可能认为客户端从它们接收通信。
服务器和 Redis
正如预期的那样,服务器将处理所有客户端连接并管理与客户端之间的所有通信。但是,当客户端发送消息时,服务器会将消息发布到 Redis,Redis 会通知其订阅者有新消息可用。从 Redis 收到消息后,每个服务器都会通知相应的客户端。
如果我们要逐步完成您的场景,它可能看起来像这样:
资源
-
负载平衡器
3 路服务器(机器 1、2 和 3)
Redis
客户端(客户端 A 和 B)
步骤
-
客户端 A 请求套接字连接
负载平衡器路由到机器 1,如有必要,还将路由所有未来的请求
套接字服务器尝试将客户端升级到双向套接字
服务器存储客户端的详细信息
客户端 B 请求套接字连接
与步骤 1 相同,但与机器 3 连接
客户端 A 向客户端 B 发送消息
客户端 A 向机器 1 发送消息
机器 1 将消息发布到 Redis
Redis 将新消息通知订阅者,包括机器 3
机器 3 将消息通知客户端 B
当然,在不向每台机器发送通知方面进行了一些优化,这在规模上会很有用,但希望这是对您需要的内容的一个很好的总结。
【讨论】:
以上是关于Socket.io 分布在不同的服务器上的主要内容,如果未能解决你的问题,请参考以下文章
socket.io 客户端可以连接到两个不同的服务器/端口吗?
Socket.io 移动到不同的域名后抛出 connect_error “服务器错误”