你真的在看两个不同的要求:
- 负载平衡:为多个 Web(或其他协议)服务器公开单个网络地址。
- 在多个服务器之间通信状态(消息)。
第一个要求很简单:使用硬件或软件负载平衡器,或者在多个 Java 服务器前使用单个 Apache Web 服务器。
第二个要求是问题。
让我们考虑单个系统上的假设聊天服务器。收到消息后,会解析请求,并将新消息放入内存中供收件人使用。需要处理常见情况:例如,用户在会话中间注销。您还需要弄清楚如何将收到的消息传递回用户的浏览器。浏览器可以轮询(“在#N 之后为用户 X 向我发送所有消息”),或者服务器可以使用多种技术之一推送接收到的消息。如果您有一个运行在 Web 服务器之上的聊天服务器,那么这一切都应该是熟悉的。
棘手的部分是:你如何在多台机器上做到这一点?在我的脑海中,我可以想到几种可以扩展的方法:
- 跟踪收件人所在的服务器。使用另一种传输机制将消息发送到该服务器,以便可以将其推送到内存中,就好像发送者是本地的一样。请参阅“消息队列”或“企业服务总线”。
- 将消息处理与通信分离:为活动对话指定一台或多台服务器。让接收服务器向这些服务器发送消息;使用通知机制(好)或轮询(不太好)来提醒收件人服务器有一条聊天消息等待发送。特殊功能:使用分布式哈希表将邮件邮箱分发到服务器池;如果一台或多台服务器出现故障,DHT 可以自动调整。
- 使用广播:如果接收者不是本地服务器,则每个服务器都向所有其他服务器广播。每个服务器都会收到通知;只有与接收者在一起的人才能对它做任何事情。
这里的关键是你不能再在多台机器之间使用共享内存。您必须使用几种可能的机制之一在服务器之间移动消息。您不太可能为此使用通用的、开销相对较高的协议(如 HTTP);有许多更高效的好工具,您可以在多个抽象级别上实现这一点,从使用像 Terracotta 这样的共享缓存工具、像 JXTA 这样的对等网络协议、像 ActiveMQ 这样的企业服务总线等. 根据你想在用户浏览器上放多少,你甚至可以直接在客户端系统上运行一些消息队列软件——有新消息的通知可以直接发送给用户,而不是发送到中间邮箱。
明确的优化是支持一种机制,将具有活动对话的用户移动到同一台服务器,但这不适用于大多数负载平衡机制。应该有某种方法可以强制用户在特定服务器之间建立关联,但我想不出一个简单的方法。