Java全栈大联盟RabbitMQ系列之可靠性投递消息延迟投递方案

资源干货第一时间送达!

今天安妮就给小伙伴们列举以下几个点:

说明:以下内容非强制或必学,做到了解即可。但是,最好熟练!

1、消息延迟投递 VS 消息落库方案

2、消息延迟投递方案

3、消息延迟投递要点

4、消息延迟投递优点

1、消息延迟投递 VS 消息落库方案

为了保证生产端的可靠性投递,上一章节提出了消息落库方案,回顾下步骤:

将订单业务数据以及订单消息进行落库(消息初始化状态为0)对数据库进行持久化操作;

发送消息给broker端;

生产端异步监听broker端返回的响应。若broker端返回值为true,则更新消息的状态值为1;

分布式定时任务,设置过期时间,定时去抓取消息状态为0的订单;

重新发送这些被分布式定时任务抓取的订单;

设置最大重试次数,超过最大阈值,则将消息状态更新为2,表示投递失败;

消息落库方案虽能提供生产端的可靠性投递,但是,它对数据库进行了两次持久化操作。在实际高并发业务场景中,每一次持久化操作都需要精心去考量。对于核心链路而言,持久化数据库的时间,能减少则尽量减少。如果对方在数据库持久化操作时花的时间比你少,那对方系统性能肯定相对而言更好。因此,如何规避这个问题,尽量减少数据库持久化操作时间,这就是第二种可靠性投递方案,即消息的延迟投递,做二次确认,回调检查。

消息延迟投递方案目的在于减少数据库操作。

2、消息延迟投递方案

首先,介绍下,图中模块表示含义:

Upstream Service表示生产端;

Downstream Service表示消费端;

MQ Broker可能是一个MQ集群;

Callback Service表示回调服务;

还是以订单为例。

第一步:先将订单业务入库,然后把消息发送到broker端的一个队列1。注意这次,我并不是再把我订单消息又存储到另外一个数据库中,这里只进行一次入库操作。

第二步:第一步发送消息后,设置一个延迟时间,比如五分钟再次发送该消息,这条消息会发送到broker端的队列2;

第三步:消费端去监听指定的队列1,对消息进行消费处理;

第四步:消费端把消息真正处理完之后,还要自己内部再生成一条新的消息叫做send confirm 确认。这条confirm的确认消息也会发送到broker端的一个队列3。

第五步:回调服务会有一个Confirm Listener去监听这个队列3,如果回调服务收到了来自消费端回送的这条confirm消息,那么,回调服务则认为消费端对数据消费成功,对这条消息做一个持久化的存储,即将消息存入MSG DB。

第六步:五分钟之后,延迟投递的消息到达broker端指定队列2。回调服务会去监听队列2,如果延迟消息到达队列2,那么回调服务就会去检查MSG DB数据库,查看这条消息是否已经被消费端消费。

若MSG DB中存在记录,则回调服务什么都不做。

若MSG DB中不存在记录,说明消费者一直没有返回响应数据或者在返回过程中由于网络原因导致返回失败,这时。回调服务会主动发起RPC通信,发送一套resend的命令(带上消息的id),告知生产者刚才发的这条消息未找到,重新重新发送。然后,生产端再重复执行第一步。

3、消息延迟投递要点

延迟投递:相比第一种消息落库方案,该方案生产端在发送消息到broker端队列1时,还额外延迟发送同一条消息到broker端另一个队列2。

回调检查:若消费端对队列1中数据消费成功,则回调服务监听到消费端的确认消费消息,会将这条消息持久化到MSG DB中。当回调服务监听到队列2的延迟消息时,检查MSG DB是否存在记录。有记录则不处理,无记录则回调服务需发送一条resend命令给生产端,执行第一步重复操作。

极端情况:如果消费端一直没有返回confirm确认消息,或者回调服务在更新MSG DB时出现异常,怎么办?延迟投递能提供补偿机制。因为五分钟之后,回调服务一定能监听到这条消息,然后去MSG DB查找该消息记录是否存在,从而决定生产端是否需要重新发送消息。

4、消息延迟投递优点

少做一次DB的存储,提高性能:

可能最开始,若执行两次insert持久化操作,可能最多每秒1000单,但如果只持久化一次,可能就是每秒2000单,这样就相当于节省一台服务器了,而且减少了这种两次持久化数据库操作可能出现的问题。

异步补偿机制,提供可靠性:两个DB实现解耦。主流核心链路:订单消息入库,生产端发送订单消息到broker端,消费者负责监听队列进行消费。Callback提供的是一个补偿服务,它不是业务高峰期的核心链路,而是将它拆出来作为一个单独的服务进行消息的异步补偿。

总结:消息延迟投递方案最大限度的节省了一次数据信息落库的操作,提高整个高并发性能。同时,回调服务提供的异步补偿机制,让生产端可靠性投递有了进一步保障。

觉得有用就转发分享一下吧

大家12月份的第三个周五愉快,与你前行

精彩内容

看完本文有收获?请转发分享给更多人

关注「Java全栈大联盟」,提升大神技能

欢迎新旧粉丝(撒花),我是Java全栈大联盟安妮。大家对微信博文有什么问题都可以@我留言,我会尽快回复大家。希望以后可以和各位成为技术道友!

安妮

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20181214G05J9O00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券