只是说下在消费过程中的幂等性问题
在消息队列中,消息重复的情况必然存在,MQTT协议中,提供了以不同的服务质量标准,从低到高分别是,
At most once:至多一次,最多被传递一次,没什么消息的可靠性,对于监控很合适,比如每分钟上报一次温度数据,可以接收数据丢失
At least once:至少一次,消息传递的时候,至少被送达一次,也就是不允许丢消息,可以有重复的消息
Exactly once: 恰好一次,消息传递的时候,只会被送达一次,不允许丢失也不允许重复
大部分的消息队列都具有这些服务质量标准,大多数也都提供了At least once的服务标准,诸如RocketMQ,RabbitMQ,Kafka
那么对于At lease once,为了避免那少量的消息重读,我们需要自己实现幂等性
Exactly once = At least once + 幂等
那么,如何设计为幂等的呢?
1.利用数据库的唯一键来实现幂等
诸如我们利用一个外键表,设置用户和账单ID为唯一约束,方便
INSERT IF NOT EXIST
2.为更新的数据设置前提条件
为数据变更设置一个前置条件,满足条件就更新数据,不然就拒绝更新,这一步,可以利用版本号来进行控制
3.记录并检查操作,我们还有种通用性更强的方式,设置一个唯一性的ID,来判断是否已经消费过了
不过这种,可能出现的问题就是操作无法保证原子性,可能出现一定的bug
可能出现A和B消费者都去消费,导致出现了数据不一致的问题
本章小结一下
我们讲解了幂等性操作的方法,不过
我们应该设置服务为幂等性,而不是强制利用消息队列保证唯一性
最后一道思考题
为何大部分的消息队列都提供At least once的服务质量,而不是更高级别的Exactly once呢?
毕竟消息队列不应该去保证幂等性,需要保证操作幂等的是服务,不能将自己的生杀大权交给外人