盘点一下我用kafka两年以来踩过的一些非比寻常的坑

本文作者分享了在使用Kafka过程中遇到的挑战,包括消息顺序、消息积压、主键冲突和数据库主从延迟等问题,以及如何通过优化解决这些问题,如调整路由规则、使用异步重试和优化消息体大小等。
摘要由CSDN通过智能技术生成

 前言

我的上家公司是做餐饮系统的,每天中午和晚上用餐高峰期,系统的并发量不容小觑。为了保险起见,公司规定各部门都要在吃饭的时间轮流值班,防止出现线上问题时能够及时处理。

我当时在后厨显示系统团队,该系统属于订单的下游业务。用户点完菜下单后,订单系统会通过发 kafka 消息给我们系统,系统读取消息后,做业务逻辑处理,持久化订单和菜品数据,然后展示到划菜客户端。这样厨师就知道哪个订单要做哪些菜,有些菜做好了,就可以通过该系统出菜。系统自动通知服务员上菜,如果服务员上完菜,修改菜品上菜状态,用户就知道哪些菜已经上了,哪些还没有上。这个系统可以大大提高后厨到用户的效率。

事实证明,这一切的关键是消息中间件: kafka ,如果它有问题,将会直接影响到后厨显示系统的功能。

接下来,我跟大家一起聊聊使用 kafka 两年时间踩过哪些坑?

顺序问题

1. 为什么要保证消息的顺序?

刚开始我们系统的商户很少,为了快速实现功能,我们没想太多。既然是走消息中间件 kafka通信,订单系统发消息时将订单详细数据放在消息体,我们后厨显示系统只要订阅 topic ,就能获取相关消息数据,然后处理自己的业务即可。

不过这套方案有个关键因素: 要保证消息的顺序 。

为什么呢?

订单有很多状态,比如:下单、支付、完成、撤销等,不可能 下单 的消息都没读取到,就先读取 支付 或 撤销 的消息吧,如果真的这样,数据不是会产生错乱?

好吧,看来保证消息顺序是有必要的。

2.如何保证消息顺序?

我们都知道 kafka 的 topic 是无序的,但是一个 topic 包含多个 partition ,每个 partition 内部是有序的。

如此一来,思路就变得清晰了:只要保证生产者写消息时,按照一定的规则写到同一个 partition ,不同的消费者读不同的 partition 的消息,就能保证生产和消费者消息的顺序。

我们刚开始就是这么做的,同一个 商户编号 的消息写到同一个 partition , topic 中创建了 4 个 partition ,然后部署了 4 个消费者节点,构成 消费者组 ,一个 partition 对应一个消费者节点。从理论上说,这套方案是能够保证消息顺序的。

一切规划得看似“天衣无缝”,我们就这样”顺利“上线了。

3.出现意外

该功能上线了一段时间,刚开始还是比较正常的。

但是,好景不长,很快就收到用户投诉,说在划菜客户端有些订单和菜品一直看不到,无法划菜。

我定位到了原因,公司在那段时间网络经常不稳定,业务接口时不时报超时,业务请求时不时会连不上数据库。

这种情况对 顺序消息 的打击,可以说是 毁灭性 的。

为什么这么说?

假设订单系统发了:”下单“、”支付“、”完成“ 三条消息。

而”下单“消息由于网络原因我们系统处理失败了,而后面的两条消息的数据是无法入库的,因为只有”下单“消息的数据才是完整的数据,其他类型的消息只会更新状态。

加上,我们当时没有做 失败重试机制 ,使得这个问题被放大了。问题变成:一旦”下单“消息的数据入库失败,用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值