scalabale应用程序中的点对点消息传递?

use*_*603 7 java queue client-server whatsapp

在谷歌搜索如何在聊天信使中发送/接收消息之后,我遇到了他们使用基于队列的消息系统.我只想弄清楚这个功能的高级设计

每个矿山的HLD理解: - 说朋友1和朋友2在线.朋友1已建立到Web服务器1的HTTP Web连接,并且朋友2已建立到Web服务器2的HTTP Web连接.朋友1将消息发送给朋友2.

现在,一旦消息到达web服务器1,我需要将消息传送到web服务器2,以便可以通过已建立的web连接将消息推回给朋友2.

我相信这里可以使用分布式自定义Java队列将消息从一个服务器传播到另一个服务器.一旦消息到达一个服务器,它就会将其推送到分布式队列(由于负载平衡和高可用性而分配队列)和消息内容,fromUserId,toUserId.队列中将有侦听器,它将看到poppedIn消息的目标userId,并查找哪个webserver目标userId处于活动状态.如果用户处于活动状态,则弹出消息并将其推送到客户端,否则将其存储在db中,以便在联机后可以将其拉出一次.要查看哪个用户在哪个服务器上处于活动状态,我们可以使用userId作为键维护树形图,将值维护为serverName以便高效查找

可能实际设计必须比上述简要更复杂/可扩展.想知道这是否是可扩展聊天信使的正确方向?

此外,我认为我们需要有多个分布式队列,而不是一个用于这种可扩展应用程序的队列.但是,如果我们有多个分布式队列,系统将如何确保跨分布式队列的FIFO消息传递?

Dim*_*mos 2

想知道这是否是可扩展聊天信使的正确方向?

使用消息队列设计此应用程序具有以下优点:

  • 客户端-服务器解耦并减少故障爆发:队列可以通过暂时增加队列大小来优雅地处理流量峰值,只要流量再次正常(或任何暂时性故障已修复),队列大小就会恢复正常
  • 在消息传递应用程序中,客户端(移动设备)可能会长时间离线。因此,同步设计将不起作用,因为客户端可能无法访问消息传递。然而,对于消息队列的异步设计,消息传递的责任在客户端。因此,客户端一上线就可以轮询新消息。

所以,是的,这种设计在性能和可用性方面具有相当大的可扩展性。唯一需要记住的是,这种设计需要为每个用户提供一个单独的队列,因此队列的数量将随着应用程序用户的数量线性扩展(这可能是一个重大的财务和可扩展性问题)。

但是如果我们有多个分布式队列,系统如何确保跨分布式队列的 FIFO 消息传递?

许多队列,无论是开源队列(rabbitMQ、activeMQ)还是商业队列(AWS SQS),都支持 FIFO 排序。然而,队列内部的 FIFO 保证还不够,因为由于网络中的异步问题,单个客户端发送的消息可能会以不同的顺序传递到队列(除非您使用单个非分布式队列和 TCP这保证了订单交付)。

但是,您可以在客户端实现 FIFO 排序。按照这种方法,消息将包含一个时间戳,每个客户端在接收消息时将使用该时间戳对消息进行排序。唯一的副作用是客户端可以看到一条消息,而无需先查看所有先前的消息。但是,当以前的消息到达时,它们将以正确的顺序显示在客户端的 UI 中,因此最终用户会以正确的顺序看到所有消息。