这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战
这个异常发生在Consumer提交位移的时候,如果发生了不可恢复的情况,我们的Consumer端就会收到这个异常信息。我们都知道Consumer端是可以进行错误重试的,但是如果是这个异常发生,是不可以进行错误重试的。所以开发过程中,要尽量避免这个异常发生
CommitFailedException发生原因
服务端在提交位移之前,发生了重平衡,并且该提交位移的分区已经交给了其他消费者管理,所以当前消费者提交位移失败,出现这种问题的原因一般是你的消费者实例连续两次调用 poll
方法的时间间隔超过了期望的 max.poll.interval.ms
参数值。这通常表明,你的消费者实例花费了太长的时间进行消息处理,耽误了调用 poll
方法。
解决方案
合理配置参数
可以通过配置poll
的最大时间间隔和减少每次poll
消息的数量来避免这个异常发生。即,
-
增加 Consumer 端允许下游系统消费一批消息的最大时长
配置
max.poll.interval.ms
参数,来增加消费者消费消息的时长,默认是5分钟。 -
减少下游系统一次性消费的消息总数
通过配置
max.poll.records
来决定每次拉取消息的数量,默认是500条,合理的缩短每次拉取消息的数量可以解决CommitFailedException
异常发生,但是如果配置的过小,势必会增加consumber与broker的交互压力。
优化业务处理
-
缩短单条消息处理的时间
假如每条消息之前的平均处理时间为
100ms
经过优化后,每条消息的处理时间优化为了50ms
这样,我们相当于程序的TPS翻了一倍,进而缩短了两次poll
的时间间隔。 -
下游系统使用多线程来加速消费。
kafka的生产端可以多个
producer
同时提交消息到broker
但是,每个consumber
处理消息确实单线程的,一条接着一条处理,所以,所以我们可以通过改进这个消费消息的模式,引入多线程并行的去处理消息,这样便可以加快消息的处理速度。有关多线程开发
Consumer
可以参考:juejin.cn/post/698887… ,但是万事万物有利便有弊,引入多线程后,需要我们管理线程间的通讯,位移提交约定,以及多个线程的生命周期以及线程数量的管理等,所以,在引入多线程之前,一定要确认是否需要引入多线程。