Kafka如何保证消息不被重复消费,这是生产环境经常面临的问题,也是大厂重点考察内容,下面我就全面来详解Kafka如何保证消息不被重复消费@mikechen
什么是重复消费
重复消费是指消息系统中的消费者,例如:(消息队列中的消费者),在某些情况下会多次接收、并处理同一条消息。
一句话总结,就是已经处理过的消息,会被“多次”处理,从而导致重复的操作。
如果消费的是你的支付宝余额,也就是说你的余额,本只扣一次钱的,会被扣多次钱。
所以,消息重复消费,在实际的业务开发中,是需要重点关注的。
重复消费的原因
为什么会出现这样的情况呢?原因如下:
1.消息确认机制问题
消费者在处理消息后,需要向消息队列确认已经成功处理了该消息。
如果确认机制有问题,比如:在处理成功后未能正确发送确认信号,消息队列会认为该消息未被处理,从而再次发送。
2.消费者故障
在消息处理过程中,如果消费者出现故障(如:崩溃、网络异常…等),且未能完成确认,也会出现这样的情况。
3.消息队列问题
例如:某些消息队列在重启、或恢复后,可能会重复发送未确认的消息。
重复消费解决方案
这里的核心,就是确保消费者业务逻辑具有幂等性,无论同一个请求执行多少次,结果都是一致的。
如下图所示:
确保消费者业务逻辑具有幂等性,即无论同一个请求执行多少次,结果都是一致的。
具体的解决方案有很多,可以结合自己的业务来定,比如:唯一标识符、更新操作代替插入操作、设计幂等操作…….等逻辑来处理。
比如,还可以使用去重表:
CREATE TABLE orders ( id INT AUTO_INCREMENT PRIMARY KEY, order_id VARCHAR(32) NOT NULL, status VARCHAR(50) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE processed_orders ( order_id VARCHAR(32) PRIMARY KEY, processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
大致流程,如下:
1、创建去重表
去重表用于记录已经处理过的操作ID,(如:消息ID、订单ID….等);
2、检查去重表
在处理操作之前,首先检查去重表中是否存在该操作ID,如果存在,说明该操作已经处理过,可以跳过处理;
3、处理操作
如果去重表中不存在该操作ID,则进行实际的业务处理;
4、记录操作
然后,业务处理完成后,将操作ID记录到去重表中。
大家可以想想这种方案有哪些问题?如何来改进?
比如:在高并发场景下,多个请求可能同时查询和插入去重表,导致并发问题。
作者简介
陈睿|mikechen,10年+大厂架构经验,BAT资深面试官,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注作者「mikechen」公众号,获取更多技术干货!

后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》,后台回复【面试】即可获取《史上最全阿里Java面试题总结》