我用kafka两年踩过的一些非比寻常的坑

本文讲述了作者在使用Kafka过程中遇到的顺序问题、消息积压、主键冲突、数据库主从延迟等问题,以及如何解决这些问题,包括保证消息顺序、优化消息体大小、调整路由规则和处理批量操作引发的连锁反应等策略,旨在分享实际操作中的经验教训。
摘要由CSDN通过智能技术生成

前言

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

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

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

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

顺序问题

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

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

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

为什么呢?

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

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

2.如何保证消息顺序?

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

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

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

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

3.出现意外

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

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

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

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

为什么这么说?

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

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

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

那么这个紧急的问题要如何解决呢?

4.解决过程

最开始我们

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值