MST

星途 面试题库

面试题:消息队列在高并发后端场景下的高级问题

在高并发的电商秒杀场景中,使用Kafka作为消息队列,如何设计消息的分区策略来确保订单处理的高效性与数据一致性,同时说明如何处理可能出现的消息重复消费问题?
15.7万 热度难度
后端开发消息队列

知识考点

AI 面试

面试题答案

一键面试

消息分区策略设计

  1. 按商品ID分区
    • 说明:将商品ID作为分区键。在电商秒杀场景中,同一商品的订单处理逻辑通常相互关联,比如库存扣减等操作。按商品ID分区可以保证同一商品的所有订单消息被发送到同一个分区。这样,消费者从该分区消费消息时,能顺序处理同一商品的订单,避免了因并发处理同一商品订单导致的库存超卖等数据一致性问题。同时,每个分区可以并行处理不同商品的订单,提高整体订单处理效率。
    • 示例:假设商品ID为1001的商品有多个秒杀订单消息,这些消息都会被发送到Kafka某个特定分区(例如分区1),消费者从分区1消费这些消息,按顺序处理商品1001的订单。
  2. 按用户ID分区
    • 说明:以用户ID作为分区键。在某些情况下,可能需要对用户的订单进行统一管理和处理,例如防止同一用户恶意刷单等场景。按用户ID分区能确保同一个用户的所有订单消息在同一个分区,便于按照用户维度进行业务逻辑处理,保证用户相关业务的数据一致性。并且,不同用户的订单处理可以并行,提升高并发场景下的处理效率。
    • 示例:用户A(ID为2001)的所有秒杀订单消息会被发送到特定分区(如分区3),消费者从分区3按顺序处理用户A的订单。

处理消息重复消费问题

  1. 幂等性处理
    • 说明:在订单处理服务中实现幂等性。幂等性操作指的是对同一操作多次执行所产生的影响均与一次执行的影响相同。例如,在处理订单时,扣减库存的操作可以设计为幂等的。每次接收到扣减库存的消息时,先检查库存是否已经扣减过(可以通过数据库记录或缓存标记等方式),如果已经扣减则直接返回成功,不再重复扣减库存。这样即使消息重复消费,也不会对库存数据造成错误影响。
    • 示例:数据库中创建一张订单处理记录表,记录每个订单的处理状态。当接收到处理订单消息时,先查询该订单在记录表中的状态,如果已经处理则不再重复处理。
  2. 唯一ID去重
    • 说明:为每个订单生成唯一ID(例如使用UUID),在消息中携带该唯一ID。消费者接收到消息时,先检查本地是否已经处理过该唯一ID对应的订单。可以使用缓存(如Redis)来记录已经处理过的订单ID,每次处理订单前先查询缓存。如果缓存中存在该ID,则说明订单已处理,直接忽略该重复消息;如果不存在,则处理订单并将ID存入缓存。
    • 示例:在订单生成时,为订单分配一个UUID作为唯一标识,如“550e8400 - e29b - 41d4 - a716 - 446655440000”。消费者在处理订单前,先向Redis查询该UUID是否存在,若存在则忽略消息。