JJava 知识库
JAVA INTERVIEW

高频面试题

Kafka高级约 2 分钟

消费者偶尔重复处理同一条支付消息,为什么会重复?业务幂等怎么做?

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

Kafka 的常见交付语义允许重复,消费端要用稳定事件 ID 和业务唯一约束,让同一支付消息多次到达只产生一次结果。

重复通常来自业务处理成功后、offset 提交前进程崩溃;rebalance、超时重试和生产者重发也会造成。我们不会追求“永远不重复”,而是让副作用幂等。

支付消息会带不可变 eventId 和支付流水号。在本地事务中先插入消费记录或直接依赖业务唯一约束,再更新订单:

INSERT INTO consumed_event(event_id, consumed_at)
VALUES (?, NOW()); -- event_id UNIQUE

若唯一键冲突,说明已经处理,返回成功并提交 offset。消费记录和订单变更必须同事务,否则记了“已消费”但订单没更新会永久漏处理。

调用外部系统时会把业务幂等号传过去;对方不支持时用本地状态机与查单补偿。Redis SETNX 可以做快速挡板,但不能作为唯一证据,因为过期、淘汰和故障转移都可能失去记录。