在Kafka中,如果消费者处理某条消息一直失败,会导致该分区的消费进度(Offset)无法提交。因为Kafka的分区是严格有序的,这条“坏消息”会像一块石头一样堵住整个分区,导致后面的正常消息也无法被消费,这种情况在业界被称为“毒药消息”(Poison Pill)或队头阻塞(Head-of-Line Blocking)。 处理这个问题的核心思想是:区分异常类型,限制重试次数,兜底转移(死信队列)。 以下是完整的处理方案和最佳实践,按从简单到高级的顺序排列: --- 第一步:区分异常类型(非常重要) 在决定如何处理之前,必须在代码中区分异常是“瞬态的”还是“永久的”: 1. 瞬态异常(Transient Exception): 比如数据库死锁、外部API网络超时、下游系统短暂不可用。这种异常值得重试,过一会儿可能就成功了。 2. 永久异常(Permanent Exception): 比如消息格式错误(JSON解析失败)、空指针异常(NPE)、非法的业务参数。这种异常重试多少次都没用,必须立刻跳过或转移。 --- 解决方案 方案一:Catch 异常 + 打印日志 + 丢弃(最简单,适...