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



在whatsapp等聊天信使中搜索消息的发送/接收方式后,我发现他们使用基于队列的消息系统。我只是在努力找出这个功能的高级设计

HLD根据我的理解:-说朋友1和朋友2在线。朋友1已经建立到网络服务器1的HTTP网络连接,并且朋友2已经建立到web服务器2的HTTP网络联系。朋友1将消息发送给朋友2。

现在,一旦消息到达网络服务器1,我就需要将消息传达给网络服务器2,以便通过已经建立的网络连接将消息推送给朋友2。

我相信分布式自定义java队列可以在这里用于将消息从一台服务器传播到另一台服务器。一旦消息到达一个服务器,它就会将其推送到具有消息内容的分布式队列(由于负载平衡和高可用性,所以是分布式队列),从UserId到UserId。队列上会有一个侦听器,它将看到刚刚poppedIn消息的目标用户ID,并找到哪个Web服务器上的目标用户Id是活动的。如果用户处于活动状态,则弹出消息并将其推送到客户端,否则将其存储在数据库中,以便可以提取一旦上网。为了查看哪个用户在哪个服务器上是活动的,我们可以在那里维护以userId为键、以serverName为值的树图,以高效地查找

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

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

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

使用消息队列设计此应用程序有以下好处:

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

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

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

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

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

Would like to know if this is the right direction for scalable chat messenger?

我可能更喜欢一种稍微不同的方法。你的想法是正确的,但我想再加一点。几年前,我碰巧创建了这样一个聊天信使,它应该与watsapp非常相似。我相信,当你在谷歌上搜索时,你会发现XMPP可扩展消息和呈现协议。我们使用openfire作为维护连接的服务器。你解释的的概念

Say Friend 1 and Friend 2 are online . Friend 1 has established HTTP web connection to web server 1 and Friend 2 has established HTTP web connection to web server 2. Friend 1 send the message to Friend 2.

称为联邦,openfire可以在联邦模式下运行。看完你的评论后,我发现每个用户点有一个队列。我相信你已经知道,这种方法是不可扩展的,因为它非常耗费资源。一个好的方法是使用像akka这样的Actor框架。在java中,每个参与者就像一个轻量级线程,每个参与者都有一个收件箱。因此,在这种情况下,会处理消息传递。

因此,您的场景转换为Friend 1,打开与openfire xmpp服务器的连接,并初始化Friend 1 Actor。当他键入一条消息时,它会转移到"朋友1"演员的收件箱中(akka中的每个演员都有一个内存收件箱)。这将被传递到xmpp服务器。服务器有自己的数据库,由于它与其他xmpp服务器联合,它将尝试查找friend 2是否在线。xmpp服务器会将消息保存在数据库中,直到好友2联机。一旦好友2建立了与任何xmpp服务器的连接,就会创建好友2参与者,并将其存在传播到所有其他服务器,xmpp服务器1将通知好友2的参与者。朋友2的演员收件箱现在将收到消息

可选:还有一个收货选项。一旦好友2读取了消息,就可以向好友1发送送达收据,以指示消息的状态,即已读、未读、已送达、未送达等。

最新更新