Kafka如何保证消息不被重复消费?

Kafka如何保证消息不被重复消费?

Kafka如何保证消息不被重复消费,这是生产环境经常面临的问题,也是大厂重点考察内容,下面我就全面来详解Kafka如何保证消息不被重复消费@mikechen

什么是重复消费

重复消费是指消息系统中的消费者,例如:(消息队列中的消费者),在某些情况下会多次接收、并处理同一条消息。

一句话总结,就是已经处理过的消息,会被“多次”处理,从而导致重复的操作。

如果消费的是你的支付宝余额,也就是说你的余额,本只扣一次钱的,会被扣多次钱。

Kafka如何保证消息不被重复消费?

所以,消息重复消费,在实际的业务开发中,是需要重点关注的。

 

重复消费的原因

为什么会出现这样的情况呢?原因如下:

1.消息确认机制问题

消费者在处理消息后,需要向消息队列确认已经成功处理了该消息。

如果确认机制有问题,比如:在处理成功后未能正确发送确认信号,消息队列会认为该消息未被处理,从而再次发送。

2.消费者故障

在消息处理过程中,如果消费者出现故障(如:崩溃、网络异常…等),且未能完成确认,也会出现这样的情况。

3.消息队列问题

例如:某些消息队列在重启、或恢复后,可能会重复发送未确认的消息。

 

重复消费解决方案

这里的核心,就是确保消费者业务逻辑具有幂等性,无论同一个请求执行多少次,结果都是一致的。

如下图所示:
Kafka如何保证消息不被重复消费?

确保消费者业务逻辑具有幂等性,即无论同一个请求执行多少次,结果都是一致的。

具体的解决方案有很多,可以结合自己的业务来定,比如:唯一标识符、更新操作代替插入操作、设计幂等操作…….等逻辑来处理。

比如,还可以使用去重表:

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面试题总结

评论交流
    暂无讨论,说说你的看法吧