上一题下一题

消息队列消费端保证至少一次投递时,重复消费、乱序和业务幂等的边界

进阶版
来源:alibaba中级工程师异常对账最终一致性消息顺序性消息幂等设计
草稿该题目为草稿状态,前台公开题库中不可见。
答案解析

消息队列如果消费端保证的是“至少一次投递”,那它的语义是:消息不会丢,但可能会被重复投递。所以在设计消费逻辑时,不能假设每条消息只会执行一次。

重复消费一般来自几个场景:消费者处理成功了,但 ack 失败;消费者处理到一半宕机,消息被重新投递;消费超时被 broker 认为失败;或者重平衡时同一批消息被新的消费者重新拉取。也就是说,重复消费不是异常情况,而是至少一次投递下必须接受的正常现象。

乱序问题也类似,很多 MQ 只能保证局部有序,比如 Kafka 只能保证同一个 partition 内有序,RocketMQ 可以通过 MessageQueue 保证队列内有序,但跨分区、跨队列、并发消费、失败重试后,都可能出现乱序。所以如果业务依赖顺序,需要把同一业务维度的消息路由到同一个队列或分区,比如按 orderId、userId 做 key,并且消费端最好单线程或按 key 串行处理。否则就不能依赖消息的全局顺序。

业务幂等的边界我一般会放在“业务状态变更”这一层,而不是只放在 MQ 层。MQ 可以做去重、重试、死信,但它不能替业务判断一条消息是否已经对业务产生过影响。真正的幂等应

登录后查看完整内容