MST

星途 面试题库

面试题:消息队列在电商秒杀高并发场景下的性能优化策略

假设电商秒杀活动每秒有上万的请求涌入,消息队列面临巨大的性能压力。请详细说明你会如何对消息队列进行性能优化,从队列的选型、架构设计到参数调优等方面展开论述。
26.9万 热度难度
后端开发消息队列

知识考点

AI 面试

面试题答案

一键面试

队列选型

  1. Kafka
    • 高吞吐量:Kafka 设计之初就是为了处理高并发的消息场景,其基于磁盘的持久化设计以及分区机制,能够在每秒处理大量消息,非常适合电商秒杀这种高流量场景。例如,在一些大型电商平台的促销活动中,Kafka 可以轻松应对每秒数万甚至数十万的消息写入。
    • 分布式架构:通过多节点的分布式集群部署,Kafka 可以实现水平扩展,增加集群的处理能力。当业务量增长时,可以方便地添加新的 broker 节点。
  2. RocketMQ
    • 低延迟:RocketMQ 在低延迟方面表现出色,能够快速处理消息,这对于电商秒杀活动中需要尽快处理订单消息等场景很关键。它采用了多种优化机制,如异步刷盘等,减少了消息处理的延迟。
    • 消息可靠性:RocketMQ 保证消息至少投递一次,并且支持事务消息,这对于电商交易场景中保证数据一致性非常重要。比如在秒杀下单过程中,涉及到库存扣减和订单创建等多个操作,事务消息可以确保这些操作的原子性。

架构设计

  1. 多队列分区
    • 对消息队列进行分区,将不同类型的秒杀消息(如商品 A 的秒杀消息、商品 B 的秒杀消息等)分配到不同的分区中。这样可以并行处理消息,提高整体处理效率。例如,在 Kafka 中,通过合理设置分区数量,可以充分利用服务器的多核资源,每个分区可以由不同的消费者线程并行处理。
    • 根据业务逻辑进行分区,比如按照用户地域进行分区。如果某地区的用户参与秒杀活动的流量较大,可以为该地区单独划分更多的分区,提高该地区用户消息的处理速度。
  2. 分层架构
    • 接入层:设置专门的接入层,负责接收大量的秒杀请求消息,并进行初步的过滤和限流。例如,可以使用 Nginx 作为接入层,通过设置限流规则(如每秒每个 IP 只能发送一定数量的请求),防止恶意请求和过多请求压垮消息队列。
    • 处理层:处理层负责从接入层接收消息,并将消息发送到消息队列。可以采用多线程或者异步处理的方式,提高消息发送的效率。同时,在处理层可以对消息进行格式转换等预处理操作。
    • 消费层:消费层从消息队列中获取消息并进行业务处理,如订单创建、库存扣减等。消费层可以采用分布式部署,通过增加消费者实例的数量来提高消息的消费速度。

参数调优

  1. Kafka 参数调优
    • producer 端
      • batch.size:适当增大 batch.size 参数值,例如从默认的 16KB 调整到 32KB 甚至更大。这样可以将多条消息批量发送,减少网络请求次数,提高发送效率。但要注意不能设置过大,否则可能会导致消息发送延迟增加。
      • linger.ms:设置 linger.ms 为一个较小的值,如 1 - 5 毫秒。该参数表示 producer 端等待消息累积到 batch.size 的时间,如果时间到了即使消息没有达到 batch.size 也会发送,通过设置较小的值可以在一定程度上减少消息发送的延迟。
    • broker 端
      • num.replica.fetchers:适当增加该参数值,比如从默认的 1 调整到 3 - 5。该参数控制每个副本从 leader 副本拉取消息的线程数,增加线程数可以提高副本同步的速度,从而提高整个集群的可靠性和性能。
      • log.retention.hours:根据业务需求调整该参数,对于电商秒杀活动,如果只需要保留短时间的消息记录以进行业务统计等操作,可以将该参数值设置得较小,如 1 - 2 小时,这样可以减少磁盘空间的占用。
    • consumer 端
      • fetch.min.bytes:增大该参数值,例如从默认的 1 调整到 1024(1KB),表示 consumer 每次从 broker 拉取消息的最小字节数。增大该值可以减少拉取次数,提高消费效率。
      • max.poll.records:根据 consumer 的处理能力合理调整该参数,如设置为 500 - 1000。该参数表示每次 poll 操作从 Kafka 拉取的最大消息数,合理设置可以使 consumer 一次处理更多的消息,提高消费速度。
  2. RocketMQ 参数调优
    • producer 端
      • sendMsgTimeout:适当延长 sendMsgTimeout 参数值,如从默认的 3000 毫秒延长到 5000 毫秒。在高并发情况下,可能会出现网络延迟等情况,适当延长超时时间可以减少消息发送失败的概率。
      • compressMsgBodyOverHowmuch:调整该参数,比如从默认的 4096(4KB)调整到 8192(8KB)。该参数表示消息体超过多大时进行压缩,适当增大该值可以减少压缩操作对性能的影响,同时又能在消息体较大时进行有效的压缩,减少网络传输压力。
    • broker 端
      • flushDiskType:可以根据业务需求将 flushDiskType 设置为 ASYNC_FLUSH(异步刷盘),异步刷盘可以显著提高消息写入的性能,但会牺牲一定的消息可靠性。在电商秒杀活动这种高并发场景下,如果能够接受一定程度的消息丢失风险(如通过业务补偿机制来处理),可以选择异步刷盘。
      • maxTransferBytesOnMessageInMemory:适当增大该参数值,如从默认的 262144(256KB)增大到 524288(512KB),表示 broker 在内存中处理消息时的最大字节数,增大该值可以提高 broker 处理大消息的能力。
    • consumer 端
      • pullBatchSize:增大 pullBatchSize 参数值,例如从默认的 32 调整到 64 - 128。该参数表示 consumer 每次从 broker 拉取消息的数量,适当增大可以提高消费效率。
      • consumeThreadMinconsumeThreadMax:根据服务器的性能合理调整这两个参数,如将 consumeThreadMin 设置为 20,consumeThreadMax 设置为 50。这两个参数分别表示消费线程池的最小线程数和最大线程数,合理设置线程数可以充分利用服务器资源,提高消息消费速度。