当前位置: 首页 > 科技观察

消息总线能否实现消息必达?

时间:2023-03-17 11:12:48 科技观察

1。origin上周在两期讨论了环形队列的业务应用:《高效定时任务的触发》《延迟消息的快速实现》在两期都有大量读者提问:任务和延时消息都保存在内存中,重启了怎么办?能保证吗?必达消息?今天简单说一下消息队列(MsgQueue)的消息传递能力的结构和过程。2.架构方向如果MQ想要消息尽可能的到达,在架构上有两个核心设计点:(1)消息落地(2)消息超时,重传,确认3.MQ核心架构上图是一个MQ的核心架构图,基本上可以分为三部分:(1)sender->左边粉色部分(2)MQ核心集群->中间蓝色部分(3)receiver->右边黄色部分pinksender由两部分组成:businesscaller和MQ-client-sender,后者为前者提供了两个核心API:SendMsg(bytes[]msg)SendCallback()蓝色的MQ核心集群分为四个部分:MQ-server、zk、db、management后台web黄色receiver也是由两部分组成:businessreceiver和MQ-client-receiver,后者为前者提供了两个核心API:RecvCallback(bytes[]msg)SendAck()MQ是系统的强大工具发布者和订阅者之间的解耦。它将上下游的消息传递解耦为两部分,如上图架构图中的箭头1和箭头2:(1)发送方将消息传递给MQ,前半部分(2)MQ将消息传递给接收者,下半部分4.MQ消息可靠传递的核心流程我们要尽量保证消息到达。MQ消息传递的前半部分,从MQ-client-sender到MQ-server的流程如上图1-3所示:MQ-client向MQ-server发送消息(此时业务方调用API:SendMsg)MQ-server会在消息落地后,表示发送成功。MQ-server将response发送给MQ-client(此时回调业务方为API:SendCallback)。MQ消息传递的后半部分,从MQ服务器到MQ客户端接收器的流程如上图4所示。6:MQ-server发送消息给MQ-client(此时回调业务方为API:RecvCallback)MQ-client回复MQ-server(此时业务方主动调用API:SendAck)MQ-server收到ack,删除之前已经落地的消息,完成消息的可靠投递。1.消息丢失了怎么办?消息丢失可能发生在MQ消息传递的前半部分和后半部分。为了降低消息丢失的概率,MQ需要超时重传。2.前半段超时重传如果MQ前半段1或2或3丢失或超时,MQ-client-sender中的定时器会重新发送消息,直到期望收到3.如果重传N次如果还没有收到,则发送SendCallback回调失败。需要注意的是,在此过程中,MQ服务器可能会收到多次重发的同一消息。3、后半段超时重传如果MQ后半段4或5或6丢失或超时,MQ-server中的timer会重新发送消息,直到收到5并执行6成功。这个过程可能会多次重发消息,一般采用指数退避策略,先每隔x秒重发一次,重发2x秒,重发4x秒,以此类推。需要注意的是,MQ-client-receiver在这个过程中也可能多次重发收到同一条消息。MQ-client和MQ-server如何对消息进行去重,以及如何设计幂等架构,下次再写。在这里,我们暂时认为,为了保证消息一定能到达,可能会收到重复的消息。五、小结消息总线是系统间强大的解耦工具,但不应该被滥用。以后会写一篇文章研究一下MQ的使用场景。为了尽可能保证消息到达,消息总线的架构设计方向是:消息先接收,消息超时,重传,确认并保证消息到达【本文为原创《58神剑》专栏作者稿件,转载请联系原作者】点此阅读更多该作者好文