资源干货第一时间送达!
今天安妮就给小伙伴们列举以下几个点:
说明:以下内容非强制或必学,做到了解即可。但是,最好熟练!
1、什么是生产端的可靠性投递
2、可靠性投递解决方案
3、消息落库方案
1、什么是生产端的可靠性投递
可靠性投递需满足四个条件:
1.保障消息的成功发出
2.保障MQ节点的成功接收
3.发送端收到MQ节点(Broker)确认应答
4.完善的消息进行补偿机制
临界值情况:
情况一:生产端投递消息失败,消费端未收到消息。
情况二:生产端投递消息了,消费端也收到了,但在返回应答过程中,突然网络中断了导致发送端未收到确认应答。
对于以上情况,只有保证以上四个条件均满足,才能实现生产端的可靠性投递。
2、可靠性投递解决方案
第一种方案:消息落库,对消息状态进行打标。
在发送消息时,要将消息持久化到数据库中,然后消息设置一个状态,如发送出去,状态为0(发送中),消息到达broker端,broker端返回响应后,将消息状态变更为1(消息已成功收到)。
但是,针对没有收到响应的消息,该怎么做?做一个轮询操作,抓取一些没有OK的消息,设置最大尝试次数,进行重新发送。
第二种方案:消息的延迟投递,做二次确认,回调检查。
3、消息落库方案
以订单为例。
第一步:消息落库。分为两个小步骤,一个是订单业务数据落库,一个是订单message落库。因此,第一件事情把订单业务数据入库(创建订单实体),第二件事情要生产一条消息,将message封装好,然后把这条消息也要入库,设置消息初始状态0,表示消息发送中。
这种方式缺点在于要对数据库数据持久化两次。这里必须保证这两步持久化操作成功,否则立即返回快速失败。
第二步:发送消息给broker
第三步:假设broker收到消息,broker将应答给生产端。
第四步:producer端会有个Confirm Listener异步的监听broker端返回的响应。如果broker端返回true,监听器监听到true后,会将这条指定的消息状态更新为1,表示这条消息已经百分之百的投递成功了。
第五步:分布式定时任务,处理极端情况。假设broker端在回送响应时,网络突然间闪断,这是MSG DB中这条消息永远是初始状态0。
这个时候需要设定一个规则,设置一个临界值timeout,比如5分钟,如果消息5分钟之内还是初始状态0,就需要将这条消息抽取出来,执行第六步重新发送。
或者定时任务设置一个定时间隔,如每隔5分钟抓取一次status为0的订单,这种可能会出现一个小问题,消息刚发出去,定时任务就开始跑了,有一些消息其实是能ACK成功的,但是分布式定时任务又重发了一遍。所以建议是设置一个消息超时的最大时间限制,如5分钟之内这条线消息还没有收到broker端的响应,status还是0,这个时候,再去抽取出来,再执行第六步重新发送。
第六步:重新发送
第七步:设置最大重试次数,超过最大重试次数,将status更新为2表示投递失败。
有一些消息它就是路由不到broker端,比如路由设置的不对,无法成功到达broker端,重试好多次都是失败的。此时需要有个重试次数的限制,如果重试次数为3,大于3次还没有收到响应,则将status设置为2,表示这条消息确认投递失败。
总结:消息投递时,必须考虑极端问题,如消费端一直收不到消息或producer一直收不到broker应答。只有处理好这种极端问题,才能保证消息的可靠性投递。
觉得有用就转发分享一下吧
大家12月份的第三个周三愉快,与你前行
精彩内容
看完本文有收获?请转发分享给更多人
关注「Java全栈大联盟」,提升大神技能
欢迎新旧粉丝(撒花),我是Java全栈大联盟安妮。大家对微信博文有什么问题都可以@我留言,我会尽快回复大家。希望以后可以和各位成为技术道友!
安妮
领取专属 10元无门槛券
私享最新 技术干货