【RabbitMQ】消息的可靠性保障和幂等性保障

可靠性保障——消息补偿机制

如何保障消息的可靠性?
如何保证消息不会丢失?
如何保证生产者发送的消息消费者一定能够正常消费掉?


这都是一个问题。之前的文章中已经介绍了几种解决方式:

(1)生产者的confirm模式。 包括Producer与Exchange之间的确认模式(ConfirmCallBack),以及Exchange与Queue之间的回退模式(ReturnCallBack)。

(2)消费者的ack机制。 包括自动签收(none)、手动签收(manual)、根据异常情况签收(auto)。

(3)消息持久化。 值得注意的是,交换机和队列的持久化(durable)和消息的持久化(persistent)并不是一回事。另外,持久化显然会影响MQ的性能,是具体情况取舍使用。


这里,再介绍一个极其重要的另一种可靠性保障机制——消息补偿。

在这里插入图片描述

延迟检查(1~7)

生产端成功操作数据库后,发送给消费端一个消息,那么,如何保证这个消息会被消费端消费呢?

首先,Producer发送消息给Consumer,Consumer如果正常消费了消息,则会发送一个确认消息,这个确认消息通过一个队列进入消息数据库(MDB);

然后,延迟一段时间后,Producer会再次发送一个消息,这个消息和刚刚发送的消息完全一样(也可以仅仅具有相同的标识),但它会进入另一个队列,并与消息数据库(MDB)中的消息进行比对,从而知道刚刚的消息是否被消费。

定时检查(8)

但是,上面的检查过程中,可能再次出现信息丢失。为了再上一个保险,每隔一段时间,还会对生产端DB与消息MDB进行比对检查。

消息补偿(RPC)

在某次检查中如果发现比对失败,便会通过一次远程过程调用(RPC)让生产者重新发一次消息。这就是消息补偿。

 
 
 

幂等性保障——乐观锁的版本控制机制

首先要搞明白,什么是幂等性(Idempotence)?

幂等性是指一次执行与多次执行对资源本身造成的影响是相同的。在MQ中,就是指Consumer消费一次数据,与消费多次数据,效果是一样的。

举个通俗的例子,Producer向Consumer发送了一个“账户金额-8000人民币”的消息,如果在MQ中出现故障,该消息出现了多个复制,或者该消息被消费者消费多次,那么用户金额可能会-100000000000。


乐观锁的数据版本机制

表中多加一个version版本号字段,它的含义通常设置为该数据被修改的次数,每次修改version加1。比如下面这个消息,它只会在version=12345时执行一次修改,之后version变为12346,与它相同的消息都不会生效,它也不会重复生效。

update account_table set money=money-8000, version=version+1 where id=2334 and version=12345

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

🐰 Rabbit~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值