只是说下在消费过程中的幂等性问题

在消息队列中,消息重复的情况必然存在,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呢?

毕竟消息队列不应该去保证幂等性,需要保证操作幂等的是服务,不能将自己的生杀大权交给外人

发表评论

邮箱地址不会被公开。 必填项已用*标注