JJava 知识库
JAVA INTERVIEW

高频面试题

Kafka高级约 2 分钟

消费一条消息后还要产生新消息,如何避免处理中断造成重复或丢失?

参考回答约 2 分钟 · 口语表达
我的判断

消费后再产生 Kafka 消息时可用 Kafka 事务原子提交输出消息和消费位点;若还写数据库,仍需 outbox 与幂等。

纯 Kafka 链路里,我会使用事务生产者:读取输入,处理后发送输出消息,再把本批消费位点通过 sendOffsetsToTransaction 加入同一事务,最后 commit。失败 abort 后,输入位点不会前进,read_committed 下游也看不到未提交输出。

poll -> beginTransaction -> send output
     -> sendOffsetsToTransaction -> commit

每个实例的 transactional.id 必须稳定且唯一,重启后通过 producer epoch fencing 旧实例。事务要短,批次和超时受控。

如果处理中还更新 MySQL,Kafka 事务不能把数据库一起纳入。我会让数据库变更和 outbox 同本地事务,再由 CDC/投递器发 Kafka;消费者和外部调用仍按 eventId 幂等。

Exactly-once 是限定边界内的处理语义,不代表邮件、支付和任意数据库副作用自动只发生一次。