文章目录
-
- 1.消息可靠性保障
- 2.消息的幂等性保障
1.消息可靠性保障
在实际生产环境中,可能会由于网络问题导致消息接收异常产生某种影响,基于这种情况我们需要保障消息的可靠性。
RabbitMQ中的消息可靠性也称为消息补偿,如下图所示,可以保证消息的可靠性。
分为9种种步骤实现消息补偿
1、生产者处理业务逻辑,将数据写入到数据库。
2、生产者将业务数据写入数据库后,向Q1消息队列发送消息数据。
3、生产者向Q1发送完消息数据后,过段时间后,会发送一个延迟消息到达Q3队列。
4、消费者从Q1队列中读取消息数据。
5、读取消息数据后,消费者根据业务逻辑向数据库中写入数据。
6.、消费者充当发布者的身份向Q2队列写入一条确认收到消息的数据,表示消费者已经收到数据并且进行了业务处理。
7、回调检查系统从Q2队列中读取消费者发送的消息数据。
8、回调检查系统再将消息数据写入到MQ数据库中,作用于记录消息传递是否成功的标志。
如果消费者接收消息出现了异常,接收失败了,第三步发送延迟消息就起到了保证消息可靠性的重要环节,生产者会发生一个延迟消息到Q3队列中,回调系统也会从Q3队列中读取延迟消息,延迟消息和正常消息是一模一样的,回调检查系统会把延迟消息的ID与MQ数据库中的消息ID进行比对,如果存在数据那么久不会再做任何处理,如果发现数据库中不存在这个消息ID,回调检查系统此时就会调用生产者重新发送消息,来保证消息传递的可靠性。
还有另外一种情况,如何延迟消息和正常消息都接收异常了,又该如何处理呢?
很简单,如上图所示,会有一个定时检查的服务,业务数据入库时也会携带消息数据的ID,用消息数据的ID去比对MQ数据库中的消息ID,当数据不存在时,定时检查服务会去调用生产者再次发生消息数据,保证消息的可靠性。
2.消息的幂等性保障
幂等性的概念:一次或者多次请求相同的资源,触发一样的业务逻辑,最终返回的结果应该是最初同样的结果,例如你9点吃早饭,那么而不管你吃了多少次早饭,都应该是9点去,不能出现不同的结果。
在MQ消息队列中,正常情况下,无论发送了多少次相同的消息,最终的结果都应该是一样的,就比如一个消息数据要扣款五百,发送了很多次,绝对不能出现多次扣款的情况。
如何保证消息的幂等性,方式有很多种,比如通过数据库的乐观锁来实现。
数据库的乐观锁主要是在数据中加上一个version字段,当通过MQ的消息触发数据库数据的修改,修改的时候匹配的条件就需要加上version这个字段,只有数据中version=1存在时修改数据,第一条消息记录造成了数据修改,那么第二条消息发送过来的时候也会匹配version=1的数据,此时就不会造成数据的修改了,因为库中已经不存在这个数据了。
如下图所示,发送时就携带了一个version=1的消息数据,消费者读取数据进行处理时,也会在数据库中查询version=1的数据进行修改,如果第一次发送过来的消息被成功处理了,version的值就会被修改,那么库中就没有version=1的数据了,即使后面发送过来多条相同的数据,条件已经不满足了,也不会被数据库修改。
第一次执行时version为1
update account set memory=memory-500,version=version+1 where id =1 and version=1
修改的数据也是匹配的version=1的数据,将数据里面的钱扣五百元,然后再将version+1,从而将version变成了2
第二次执行时,version已经是2了,从而无法匹配数据无法进行操作,保证数据的幂等性
update account set memory=memory-500,version=version+1 where id =1 and version=1