1. 消息如何保障100%的投递成功?
1.1 什么是生产端的可靠性投递?
(1)保障消息的成功发出
(2)保障MQ节点的成功接收
(3)发送端收到MQ节点(Broker)确认应答
(4)完善的消息进行补偿机制
1.2 生产端-可靠性投递
互联网大厂的解决方案:
(1)消息落库,对消息状态进行打标
(2)消息的延迟投递,做二次确认,回调检查
保障MQ我们思考如果第一种可靠性投递,在高并发的场景下是否适合?
答案是不适合,第一种数据库操作比较耗时,所以在第二种方法中,我们要减少数据库操作。做到消息的延迟投递,做二次确认,回调检查。
先入库(BIZ DB),再发送消息。一次生成两条消息,第二步(Second Send Delay Check)在第一步消息发出之后再发送,间隔时间自己定,可能是2分钟、5分钟。
2. 幂等性概念及业界主流解决方案
2.1 幂等性概念
幂等性是什么?
我们可以借鉴数据库的乐观锁机制:比如我们执行一条更新库存的SQL语句
如果是并发更新操作,我们为了避免数量被减为负数,设置了版本号,更新时带上版本号,还有商品id
UPDATE T REPS SET COUNT= COUNT-1,VERSION= VERSION+1
WHERE VERSION=1
幂等性就是对一条数据进行操作,无论执行多少次,结果都是一致的,不会因为多次操作而产生副作用。
2.2 在海量订单产生的业务高峰期,如何避免消息的重复消费问题?
消费端实现幂等性,就意味着,我们的消息永远不会消费多次,即使我们收到了多条一样的消息
2.3 业界主流的幂等性操作:
(1)唯一D+指纹码机制,利用数据库主键去重
唯一ID+指纹码机制,利用数据库主键去重
SELECT COUNT(1)FROMT ORDER WHERE ID=唯一ID+指纹码
好处:实现简单
坏处:高并发下有数据库写入的性能瓶颈
解决方案:跟进ID进行分库分表进行算法路由
(2)利用Redis的原子性去实现
使用Redis进行幂等,需要考虑的问题:
第一:我们是否要进行数据落库,如果落库的话,关键解决的问题是数据库和缓存如何做到原子性?
第二:如果不进行落库,那么都存储到缓存中,如何设置定时同步的策略?