在谷歌搜索如何在聊天信使中发送/接收消息时,我遇到了他们使用基于队列的消息系统。我只是在尝试 找出这个功能的高级设计
每个矿山的HLD理解: - Say Friend 1和Friend 2在线。朋友1已建立到Web服务器1的HTTP Web连接,并且Friend 2已建立到Web服务器2的HTTP Web连接。朋友1将消息发送给朋友2。
现在,只要消息到达Web服务器1,我就需要将消息传送到Web服务器2,以便可以通过已建立的Web连接将消息推送回朋友2。
我相信分布式自定义Java队列可以在这里用于将消息从一个服务器传播到另一个服务器。一旦消息到达一个服务器,它就会将其推送到分布式队列(由于负载平衡和高可用性而分配队列)和消息内容,fromUserId,toUserId。队列中将有侦听器,它将看到poppedIn消息的目标userId,并查找哪个webserver目标userId处于活动状态。如果用户处于活动状态,则弹出消息并将其推送到客户端,否则将其存储在db中以便可以将其拉出 一旦上线。要查看哪个用户在哪个服务器上处于活动状态,我们可以使用userId作为键来维护树形图,并将值作为serverName进行维护以便高效查找
可能实际设计必须比上述简要更复杂/可扩展。 想知道这是否是可扩展聊天信使的正确方向?
此外,我认为我们需要有多个分布式队列,而不是一个用于这种可扩展应用程序的队列。 但是,如果我们有多个分布式队列,系统将如何确保跨分布式队列的FIFO消息传递?
答案 0 :(得分:2)
想知道这是否是可扩展聊天的正确方向 信使?
使用消息队列设计此应用程序具有以下好处:
所以,是的,这个设计在性能和可用性方面可以提供很大的可扩展性。唯一要记住的是,这种设计需要为每个用户分别设置一个队列,因此队列数量会随着应用程序用户的数量线性增长(这可能是一个重要的财务和可扩展性问题)。
但是如果我们有多个分布式队列,系统将如何确保 跨分布式队列的FIFO消息传递?
许多队列,无论是开源(rabbitMQ,activeMQ)还是商业(AWS SQS),都支持FIFO排序。但是,队列中的FIFO保证是不够的,因为由于网络中的异步性问题,单个客户端发送的消息可能以不同的顺序传递到队列(除非您使用单个非分布式队列和TCP保证订购交货)。
但是,您可以在客户端实现FIFO排序。按照这种方法,消息将包括一个时间戳,每个客户端将使用该时间戳在接收消息时对消息进行排序。唯一的副作用是客户端可以看到消息,而不会先看到所有先前的消息。但是,当先前的消息到来时,它们将在客户端的UI中以正确的顺序显示,因此最终用户将以正确的顺序看到所有消息。
答案 1 :(得分:1)
Would like to know if this is the right direction for scalable chat messenger?
我可能更喜欢略有不同的方法。你的想法是正确的,但我想补充一点。几年前我碰巧创建了这样一个聊天信使,它应该与watsapp非常相似。我确信当你用Google搜索时,你会遇到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可以联合模式运行。阅读完评论后,我发现每个用户点都有一个队列。我相信你已经知道这种方法不是可扩展的,因为它非常耗费资源。一个好的方法是使用一个Actor框架,如akka。每个actor都像java中的轻量级线程,每个actor都有一个收件箱。所以在这种情况下消息传递得到了解决。
所以你的场景转换为朋友1打开了与openfire xmpp服务器的连接并初始化了一个朋友1的演员。当他输入一个消息时,它被转移到朋友1演员的收件箱中(akka中的每个演员都有一个内存)收件箱)。这将传达给xmpp服务器。服务器有自己的数据库,由于它与其他xmpp服务器联合,它将尝试查找朋友2是否在线。 xmpp服务器将消息保留在其数据库中,直到朋友2联机。一旦朋友2建立到任何xmpp服务器的连接,就创建了一个朋友2 actor并且它的存在被传播到所有其他服务器,并且xmpp服务器1将通知朋友2的演员。朋友2的演员收件箱现在将收到消息
可选:还有一个送货回执选项。一旦Friend2读取该消息,就可以将发送收据发送给朋友1以指示该消息的状态,即读取,未读取,已发送,未发送等。