如何保证消息不重复的?
如何保证消息不重复的?
提示
题眼: 幂等,幂等,还是幂等
这个问题,算是消息队列里比较简单的问题了,解决思路业务里的接口幂等一样,一般通过一个唯一 trace_id 来实现。
重要
参考答案:
消息不重复的话,一般需要消费端来解决,因为 kafka 本身是不会去重的,然后生产端因为有重试机制,肯定会出现重复消息。一般情况下,我们服务在中间件这边会在用户请求进来的时候,在中间件这边塞一个 TraceID 进去,一方面当链路追踪使用,另一方面可以作为业务行为的幂等操作使用。
当消费端收到消息以后,正常处理业务逻辑,比如说更新数据库之类的,会同时把这个 id 记录到库里面,后面再收到消息时,可以比对下上次操作的 ID 和这次的 ID 是否一致,如果一样,就认为是重复消息。
除了这一种,如果是比较简单的场景,可以用 MySQL 、Redis 的特性来做唯一性,比如说写入数据的时候,利用唯一索引的特性,让后续重复数据写入失败。
这两个方案,主要是解决我们系统产生的重复消息,还有一种情况,是用户主动触发的重复消息。比如说,我们投票系统里,因为用消息队列异步了投票操作,有些用户会多次投票。像这种,就需要用 Redis 做个状态记录,如果已经投过票了,就直接返回,不再发送消息。
相关信息
引申: TraceID 在极端情况下,重复了怎么办?(增加消息的有效时间,三分钟内重复消息,不处理)
