每年夏天,住在清江上游的水库管理员老陈都会盯着水位标尺发愁。暴雨总在午后突然砸下来,山洪裹着泥沙冲进河道——如果让这些水直接涌向下游的农田和居民区,后果不堪设想。老陈的应对办法很简单:把暴涨的水拦进水库,按下游能承受的速度慢慢放出去。等到雨停了,水位再一点点降回安全线。这就是“削峰填谷”。 在互联网系统里,每天也有无数场“暴雨”:秒杀活动的订单洪峰、AI应用上线当天的请求狂潮、大模型API被某个热点事件瞬间打爆的流量。后端服务就像下游河道,容量是固定的,硬扛洪峰只会被冲垮。消息队列就是那座水库。本篇文章将带你从水库管理员老陈的视角,理解消息队列如何削峰填谷、如何监控水位、如何预估洪峰,以及 Kafka 与 RabbitMQ 这两座不同“坝型”的差别。

岗位关联

消息队列削峰填谷是构建高可用系统的核心基本功。掌握它,你才能在高并发架构设计、容量评估和线上故障排查中游刃有余,为 AI 推理服务、特征管道、训练数据投喂等场景保驾护航。

目录
  1. 可视化演示
  2. 洪峰成因:暴雨从哪来
  3. 缓冲原理:水库的蓄与泄
  4. 稳态消费:匀速放水的闸门
  5. 背压机制:下游传来的压力
  6. 堆积监控:水库水位标尺
  7. 峰值预估:提前看天气预报
  8. 引擎对比:土坝与混凝土坝
  9. 生产复盘:老陈的防汛手册
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示消息队列将瞬时写入峰值平滑为后端稳态消费的缓冲机制,对比Kafka与RabbitMQ性能差异,可视化监控指标体系。

本节配有交互动效(进入视口后自动加载,约 3KB)。

削峰填谷三环节 生产者峰值写入→消息队列缓冲→消费者稳态消费 消费端背压机制限制消费速率保护后端 Q=Peak-In−Avg-Out 队列堆积量=峰值速率-消费速率

洪峰成因:暴雨从哪来

老陈的台账上记录着每一场暴雨的脾气:午后骤雨来得急去得快,台风过境能连下两天,上游水库泄洪则是人为的“错峰”。来水的形态不同,但有一点是共同的——它们都让河道在短时间内承受了几倍于平时的水量。

软件系统里的“暴雨”同样有迹可循,最常见的洪峰有四种:流量突刺(热点链接被病毒式转发、爬虫集中抓取)、秒杀洪峰(电商大促瞬间涌入海量下单请求)、慢请求拖尾(一个接口变慢占满了连接池,其他请求排队等待,像河道被巨石堵住)、下游雪崩(核心依赖故障引发连锁反应,整个调用链次第倒下)。

这四种洪峰的本质是共同的:瞬时写入速率远远超过后端服务的稳态处理能力。如果让订单服务直接面对每秒数万次写入,数据库连接池会最先被打满,线程阻塞、CPU飙升,最终整体宕机。这就是高并发设计的第一课——不是先优化数据库,而是先给洪峰找一个缓冲区。

老陈明白,暴雨无法阻止,只能提前应对。架构师也一样:流量洪峰是互联网的“天气”,我们改变不了天气,但可以修建水库。

缓冲原理:水库的蓄与泄

老陈的水库之所以能让下游安然无恙,靠的不是“挡”,而是“蓄”与“泄”的配合。洪峰来了,水先存进库区;闸门按固定开度放水;雨停了,继续以恒定流速下泄,直到水位回落到安全线。整个过程下来,上游虽然经历了暴涨,下游看到的却始终是平稳的来水。

消息队列就是软件世界的蓄水池。生产者无论多快地把消息写入 Broker(队列的存储节点),消费者始终按自己的节奏拉取处理。消息暂时堆积在队列节点上,既不会阻塞上游,也不会压垮下游。这带来两个关键收益:一是削峰,峰值写入被缓冲;二是异步解耦,生产端和消费端的流速彼此独立,不再互相拖累。

排队论中的 M/M/1 模型可以描述这种缓冲行为。假设消息到达率为 λ(每秒新写入的消息数),消费者的处理率为 μ(每秒能处理的消息数),则队列的平均堆积长度为:

老陈心里有本账:闸门放水能力大于平均来水,水库才能守住。架构师也只需记住一句话——稳态下处理能力必须大于平均流量,这就是削峰填谷的前提。

Nˉ=λμ−λ\displaystyle \bar{N}=\frac{\lambda}{\mu-\lambda}
平均堆积长度公式:队列里已积压的数量不是随便涨的,它由“来水速度”和“处理能力”之间的差值共同决定。差值越小,积压越少。
  1. 到达率 λ单位时间内进入队列的新消息数量,相当于暴雨的来水强度——雨越大,λ 越大。
    λ=Marrivalt\lambda = \frac{M_{\text{arrival}}}{t}
  2. 处理率 μ单位时间内消费者能从队列取走并处理完的消息数量,相当于闸门的泄洪上限。
    μ=Mprocessedt\mu = \frac{M_{\text{processed}}}{t}
  3. 分母 μ−λ处理能力减去到达速度,代表队列的净排空能力。只有 μ>λ 时系统稳定,否则堆积会无限增长。
    μ−λ>0\mu - \lambda > 0
  4. 平均堆积 N̄用到达率除以剩余处理能力,得到稳态下队列中的平均消息条数。处理能力越接近来水速度,分母越小,堆积越长。
    Nˉ=λμ−λ\bar{N}=\frac{\lambda}{\mu-\lambda}

稳态消费:匀速放水的闸门

老陈开闸有一个铁规矩:不论上游来多大水,闸门开度只服从一个原则——下游河道当前能承受多少。上午河床浅,少放些;晚上清淤后,多放些;但绝不允许超过安全流量。

消费端也一样。很多人以为“队列里有消息就该立刻消费”,但削峰填谷的精髓恰恰是让消费速率对齐下游的承受能力。Kafka 通过 max.poll.records 配置单次批量拉取的条数,RabbitMQ 通过 prefetch 设置消费者的预取上限。批量拉取加上批量处理,是压榨吞吐量的第一杠杆——一次网络往返处理几十条消息,远比逐条处理高效。

消费吞吐量 R 可以用一个简单的公式描述——批大小 B(每次拉取多少条)除以单批耗时 t(处理完这批消息花多少时间):

老陈从不在意一场雨下了多大,只关心闸门按安全流量放水一天,下游还撑不撑得住。消费者也当如此:不追峰值,只追稳态。

R=Bt\displaystyle R=\frac{B}{t}
消费吞吐公式:单位时间真正处理完的消息数。批量越大、单批耗时越短,每秒处理得就越多。
  1. 批大小 B每次从队列拉取的消息条数。批量越大,网络往返和线程切换的开销摊得越薄。
    BB
  2. 单批耗时 t处理完这一批消息花费的总时间,包含业务逻辑、网络调用与提交确认。
    tt
  3. 吞吐率 R两者相除得到每秒实际处理的消息条数,是衡量消费端能力的关键指标。想提高吞吐,要么加大 B,要么缩短 t。
    R=BtR=\frac{B}{t}

背压机制:下游传来的压力

有一年汛期,老陈发现下游河堤出现管涌。如果继续按正常流量放水,河堤随时会崩。他立刻把闸门关小,同时打电话通知上游水电站暂停泄洪。水流变小了,下游保住了。这股“从下游传回来的压力”,就是背压。

在系统中,当消费端处理不过来,或它的下游依赖(数据库、外部 API、磁盘)出现瓶颈时,队列需要通过某种机制把压力反向传导到上游,让消息流入减速,而不是无限积压。常见的背压实现包括:调整 prefetch 限制消费者的拉取速率、RabbitMQ 的 basic.qos 配合 reject 让消息回拒、Kafka 消费者 poll 超时触发分区重新分配。

背压的核心价值是保护,让系统在过载时优雅降级而不是突然崩溃。Kafka 的 max.poll.interval.ms 是一道背压防线:消费者处理一批消息超过该时间仍未 poll,Broker 就判定它失联,触发 rebalance(把分区转给健康消费者重新分配)。RabbitMQ 的 prefetch 限制则防止单个消费者囤积过多消息导致内存暴涨。如果背压持续太久,就需要扩容消费实例来提升整体排水能力,让水位尽快降下来。

老陈关闸不是认怂,而是为下游争取修复时间。背压也是一样——它不是系统故障的表现,而是系统自我保护的智慧。

堆积监控:水库水位标尺

对老陈来说,下多大的雨不可怕,可怕的是不知道水库还能撑多久。所以他每天都要看水位标尺:现在多少米?距警戒线还有多远?按现在的放水速度,排完需要多久?

消息队列的“水位”由三组指标刻画:积压消息总数 Q(当前排队的消息条数)、消费延迟 Lag(最新消息被消费的时间差)、积压排空时间 T(按当前净处理速度清空积压的预估时长)。Kafka 用 consumer lag 作为核心监控对象,RabbitMQ 在管理界面展示 ready 和 unack 数量——它们都是水位的刻度。

假设当前积压 Q 条,消费速率为 μ,生产速率为 λ,净排水速度为 μ−λ,则排空时间为:

老陈在坝体上画了红黄两道警戒线——水位过黄线要关注,过红线要启动应急预案。架构师也应把积压量达到容量的 70% 设为关注阈值,90% 设为处置阈值,不要等水漫过墙顶才反应。

T=Qμ−λ\displaystyle T=\frac{Q}{\mu-\lambda}
排空时间公式:积压量除以净消化速度,得到水位回落到零需要的时间。这个数字直接告诉你“要不要立刻扩容”。
  1. 积压量 Q当前队列中等待处理的消息总数,就是水库此时此刻的水位。
    QQ
  2. 净排水速率 μ−λ消费端每秒处理量减去上游每秒新来量,表示真正消化存量的速度。
    μ−λ\mu-\lambda
  3. 排空时间 T两者相除得到清空积压所需秒数。净排水速率为正,积压逐步缓解;为负,水位继续上涨。
    T=Qμ−λT=\frac{Q}{\mu-\lambda}

峰值预估:提前看天气预报

每年入汛前,老陈都盯着天气预报做一道算术题:如果最大暴雨持续 6 小时,水库要预留多少库容才不溢洪?提前腾库容,雨来了才不会慌。

大促、秒杀、AI 应用发布前,架构师也要做同样的算术题。流量预估的来源包括历史同级别活动的数据、全链路压测的结果,以及业务运营给出的预测数字。基于预估的峰值速率和持续时长,就能算出消息队列需要多大的缓冲容量。估算不足,洪峰直接打穿队列冲击后端;估算过大,机器成本白白浪费。

队列容量 C 的预估公式,就是把峰值速率、持续时长和冗余系数三者相乘:

老陈每年宁可多腾一点库容,也绝不让水漫过坝。真实系统中,预留的容量就是弹性扩缩容的底气——云上环境还可以结合自动扩缩容,让队列的消费能力和存储空间随水位动态调整。

C=Ppeak×Tpeak×(1+r)\displaystyle C=P_{\text{peak}}\times T_{\text{peak}}\times(1+r)
容量预估公式:峰值每秒条数乘以持续秒数,得到理论总消息量,再乘上冗余系数留出安全边际。
  1. 峰值速率 P_peak洪峰期间每秒最大消息到达数,通常取历史峰值流量或压测数据。
    PpeakP_{\text{peak}}
  2. 持续时长 T_peak洪峰预计持续的秒数,注意要将小时换算成秒再代入。
    TpeakT_{\text{peak}}
  3. 冗余系数 1+rr 为冗余率(如 0.3 表示多预留 30%),用来吸收预估误差与突发抖动。
    (1+r)(1+r)
  4. 总容量 C三者相乘得到需要预留的队列容量,单位是“条消息”。这就是大促前给 Kafka 或 RabbitMQ 配置的底气。
    C=Ppeak×Tpeak×(1+r)C=P_{\text{peak}}\times T_{\text{peak}}\times(1+r)

引擎对比:土坝与混凝土坝

水库也分坝型。上游那座大型混凝土坝蓄水量巨大,但结构笨重、调度复杂;下游那座带闸门的小土坝灵活轻便,却蓄不了大水。老陈知道,选哪座坝取决于来水多大、下游需要什么。

Kafka 和 RabbitMQ 就是消息队列世界里最常用的两座“坝”。Kafka 基于日志追加架构,吞吐量可达百万条/秒,天然支持消息回放与长时间堆积,适合大规模数据管道和极高并发削峰;RabbitMQ 基于 AMQP(一种消息投递协议),支持灵活的路由——direct 直连、topic 通配、fanout 广播三种交换机模式,以及精细化的消息确认,在万条/秒级别的业务系统中有着丰富的生态。

选型时可以对比四个维度:吞吐与堆积能力(Kafka 明显占优)、消息确认机制(RabbitMQ 更细)、路由灵活性(RabbitMQ 更丰富)、运维复杂度(Kafka 的元数据管理和分区均衡更复杂,RabbitMQ 开箱即用)。所以秒杀、日志、流处理用 Kafka;业务异步解耦、复杂消息路由选 RabbitMQ。

老陈的结论是:没有最好的坝,只有最合适的坝。选型前先回答三个问题:来水多大?下游扛不扛得住?业务要不要复杂的调度?

生产复盘:老陈的防汛手册

老陈的抽屉里有一本磨破边的防汛手册,记录着每场暴雨的时间、水位、处置步骤和事后反思。第二年遇到相似天气,翻开手册就能少走弯路。

这本手册对应着技术人的故障复盘。以某电商秒杀案例为例:开场仅 3 分钟,订单消费积压从 2000 条猛涨到 20 万条,Kafka 消费延迟飙到 30 秒。团队一开始判断“消费者不够”,把实例从 10 个扩到 50 个,延迟却不降反升。进一步排查才发现:下游订单数据库的连接池只有 30 个连接,所有消费线程都阻塞在等待数据库连接上。

那次事故沉淀了四条排查路径:一看监控,先确认积压量、消费延迟和消费者线程状态;二判瓶颈,用压测和数据判断是生产端、Broker 还是消费端的问题;三找根因,深入代码和依赖,本次根因是连接池配置过低;四做处置,修复连接池、扩容消费者,同时跳过积压的冷数据追赶进度。复盘后团队把“洪峰期前压测数据库连接池”写进了上线规范,同类事故再没出现过。

防汛手册越写越厚,老陈的险情却一年比一年少。架构能力也是在一次次复盘与积淀中提升的——这才是削峰填谷工程实践的真正闭环。

AI 应用场景

大模型 API 网关削峰填谷

阶段:模型推理服务部署与流量治理

解决的问题:大模型 API 的请求量常因热点事件突然暴涨(AI 新品发布、名人效应、社交平台热转),而 GPU 推理集群资源昂贵,无法按峰值无限扩容。传统同步方案下,突发流量会直接打满推理服务导致超时雪崩。引入 Kafka 作为请求缓冲后,推理 Worker 以固定速率消费请求并调用 GPU,推理吞吐保持平稳,用户体验从“服务崩溃”变成“排队等待”。

具体案例:某 AI 绘画应用上线爆火,单日请求峰值是预估的 5 倍。API 网关把请求先写入 Kafka,后端 8 台 GPU 推理机以每台每秒 40 条的速率稳定消费,高峰期用户排队约 20 秒,但系统零故障。

推荐系统特征管道削峰

阶段:特征计算与实时数据管道

解决的问题:推荐系统的实时特征计算在晚间高峰流量激增,直接同步计算会打爆 Redis 和特征存储。用 RabbitMQ 做异步缓冲,特征计算服务按固定节奏批量处理,让在线特征时效性保持稳定,在“洪峰”来临时不慌不忙。

具体案例:某短视频平台晚间 20:00–22:00 流量为平日的 3 倍,特征服务通过 RabbitMQ 削峰,将实时特征计算延迟稳定控制在 50ms 以内。

训练数据管道平稳投喂

阶段:训练数据采集与预处理

解决的问题:业务高峰期的日志采集会产生海量数据洪峰,直接写入训练集群会冲击数据加载,导致 GPU 空等或 OOM。Kafka 先将海量日志削峰暂存,训练数据预处理 Job 按批均匀拉取,稳定喂给 GPU,让训练集群始终处于满负荷工作状态。

具体案例:某推荐大模型训练前,将一周的日志通过 Kafka 缓冲后均匀消费,训练集群吞吐稳定,Kafka 积压峰值达数亿条仍无压力。

Python 演示

python39 行
import random  class PeakShavingQueue:    """模拟消息队列:缓存突发消息,供下游匀速消费"""     def __init__(self, consume_rate=8):        self.items = []   # 消息堆积区(水库蓄水)        self.consume_rate = consume_rate  # 下游固定消费速率     def produce(self, count):        for _ in range(count):            self.items.append("msg")     def consume_once(self):        picked = min(self.consume_rate, len(self.items))        self.items = self.items[picked:]        return picked  def simulate(runtime=24):    queue = PeakShavingQueue(consume_rate=8)    for sec in range(1, runtime + 1):        # 前8秒正常流量,第9-18秒出现洪峰,之后回归平稳        if 9 <= sec <= 18:            arrival = random.randint(20, 40)        else:            arrival = random.randint(2, 6)        queue.produce(arrival)        processed = queue.consume_once()        backlog = len(queue.items)        marker = "  <== 洪峰" if arrival >= 20 else ""        print(f"第{sec:2d}秒 到达={arrival:2d} 处理={processed:2d} 堆积={backlog:3d}{marker}")        if backlog > 100:            print("        !!! 水位告警:堆积超过 100 条 !!!")  if __name__ == "__main__":    simulate()
目的:用 24 秒模拟一场小型“汛期”——洪峰期每秒到达 20–40 条消息,下游每秒只处理 8 条,队列蓄水削峰,演示削峰填谷的全过程。
  1. self.items = []模拟队列的蓄水空间,消息先堆在这里等待下游消费
  2. def consume_once(self):每次按固定速率处理消息,相当于闸门匀速放水
  3. picked = min(self.consume_rate, len(self.items))最多消费 N 条,不足 N 条就全取出来
  4. if 9 <= sec <= 18:模拟洪峰期,生产者每秒产生 20–40 条消息
  5. backlog = len(queue.items)统计当前堆积消息数,就是水库实时水位
  6. if backlog > 100:模拟堆积监控告警,水位过高时提醒人工介入

常见误区

误区积压一严重,第一反应就是疯狂扩容消费者实例,以为机器多了自然就消了。可有时候扩容后延迟反而更高,问题根本没解决。

正解扩容只是“加大闸门”,如果下游依赖(数据库连接池、外部 API、磁盘 IO)才是真正的瓶颈,扩再多消费者也只会让下游更拥堵。正确做法是先用监控确认瓶颈在哪一端:消费线程是否空闲?数据库连接是否被打满?如果是下游故障,先修复依赖,再考虑扩容。这就像老陈开大闸门之前,得先确认下游河道没有管涌。

为何常见:人们习惯用“加机器”这种线性思维处理性能问题,忽略了瓶颈往往在下游,而非消费端本身。

误区听过“Kafka 百万级吞吐”后,就认为所有消息队列场景都应该用 Kafka,RabbitMQ 性能不行。

正解吞吐量只是选型维度之一。RabbitMQ 在低延迟、灵活路由(direct/topic/fanout 交换机)、精细化消息确认上有独特优势,很多企业内部业务系统选用 RabbitMQ 开发效率更高。Kafka 强在超高吞吐、堆积持久化、消息回放,但运维复杂度也更高。就像选土坝还是混凝土坝,要看上游来水多大、下游需要什么,而不是盲目追求“最大坝”。

为何常见:技术选型容易被“最高性能”的唯一标准带偏,忽略了场景匹配、团队熟悉度和运维成本。

误区以为消息队列是保险箱,消息交进去就万无一失,不配置持久化和副本也没关系。

正解消息可靠性需要三重保障:Broker 磁盘持久化与多副本、生产者 ack 机制、消费者手动提交 offset/ack。默认配置往往偏向性能而非可靠性——例如 Kafka 的 acks=0、RabbitMQ 非持久化队列,宕机或重启都会丢消息。削峰填谷不等于丢弃消息,而是暂时存储后平滑消化;只有配置到位,水库才是一座不渗漏的坝。

为何常见:把消息队列想象成“绝对可靠的黑盒子”,忽略了分布式系统的默认配置常常牺牲可靠性来换吞吐。

误区雨停了水库水位自然会降,所以队列堆积时只要等着就行,过一会儿自己就空了。

正解如果积压期间生产速率仍然大于或接近消费速率,积压只会持续增长;即使洪峰结束,排空时间 T=Q/(μ−λ) 也可能长达小时级。若消费端处理的是“过时”数据,还要考虑冷数据的价值衰减。必须主动控制:扩容消费者、降低生产者速率、跳过冷数据或调整消费优先级。老陈会在暴雨后连夜加大放水量,而不是等太阳把水库晒干。

为何常见:人容易低估“存量”的处理时间——直观上觉得暴雨停了水就退了,却忽视了水库已经蓄满了水。

面试题

Q1. 消息队列削峰填谷的核心思想是什么?

单选题 · easy

  • A.增加生产端的发送速度
  • B.缓冲峰值并平滑输出← 正确答案
  • C.直接丢弃多余的消息
  • D.压缩队列中的存储空间

答案:B。削峰填谷本质是水库思想:把高峰流量暂存进队列,以稳定速率交给下游,而不是增快或丢弃。A 方向反了,C 是限流策略而非削峰,D 与缓冲无关。

Q2. 在 M/M/1 排队模型中,当消息到达率 λ 不断增大并趋近处理率 μ 时,队列平均长度会发生什么?

单选题 · mid

  • A.缓慢趋于一个固定值
  • B.保持原有数值不变
  • C.迅速增大趋向无限大← 正确答案
  • D.直接降为零并维持

答案:C。由 N̄=λ/(μ−λ) 可知,λ→μ 时分母趋近 0,平均堆积迅速爆炸。这解释了为什么必须让处理能力明显大于平均到达率,就像闸门放水能力必须大于平均来水一样。

Q3. 下列关于背压的说法,哪些是正确的?

多选题 · mid

  • A.背压由消费端传向生产端← 正确答案
  • B.背压保护下游不被压垮← 正确答案
  • C.背压一定会导致丢消息
  • D.背压通过限流反向传导← 正确答案

答案:ABD。背压是下游处理不过来时向上游反馈压力、限制流入,是保护机制而非故障;它不会主动丢消息,只是让生产者等待或降速,所以 C 错误。

Q4. 削峰填谷场景中,消费者应该采用哪种处理节奏?

单选题 · easy

  • A.有消息立即全量消费
  • B.稳定速率批量拉取← 正确答案
  • C.只在洪峰期才消费
  • D.消费速率跟随生产波动

答案:B。削峰的目的就是把消费速率稳定下来。按稳定速率批量拉取能提高吞吐并保护下游,A 会让下游依然承受波动,C 和 D 违背了“填谷”的初衷。

Q5. 监控消息堆积时,哪些指标能反映队列健康状况?

多选题 · mid

  • A.当前积压的消息总数← 正确答案
  • B.消费端消息处理延迟← 正确答案
  • C.生产端网络带宽占用
  • D.预估积压排空所需时间← 正确答案

答案:ABD。积压总数、消费延迟和排空时间直接反映“水位”和消纳速度;生产端网络带宽是前置网络指标,与队列内部健康关系较弱,就像看水库水位不必关心降雨云在哪儿。

Q6. 大促前预估队列容量 C,已知峰值速率 P_peak=5000 条/秒,持续 T_peak=2 小时,冗余系数 r=0.3,则 C 约为多少?

单选题 · hard

  • A.约 3600 万条
  • B.约 3960 万条
  • C.约 4680 万条← 正确答案
  • D.约 1800 万条

答案:C。C=5000×7200×1.3=4680 万条。A 漏乘冗余系数,B 把 1.3 错用成 1.1,D 把时长少算了一半(只算 1 小时)。这就是公式 C=P_peak×T_peak×(1+r) 的实战应用。

Q7. RabbitMQ 相比 Kafka 在削峰场景中的主要优势是什么?

单选题 · mid

  • A.吞吐量更高扩展性更强
  • B.路由灵活确认机制丰富← 正确答案
  • C.无需任何配置即可使用
  • D.天然支持日志流式重放

答案:B。RabbitMQ 的强项是 flexible 路由、精细确认和低延迟;高吞吐和日志流式重放是 Kafka 的强项。C 不现实,任何中间件都需要配置调优。

Q8. 当线上队列积压严重时,合理的处置措施有哪些?

单选题 · extreme

  • A.立刻停止所有消费进程← 正确答案
  • B.扩容消费端实例数量
  • C.排查下游依赖是否故障
  • D.跳过价值低的冷数据

答案:A。等等,这道题是多选,正确答案是 [1,2,3]。A 停止消费会让积压更严重,完全错误;B 扩容提升排水能力,C 定位根因,D 跳过冷数据追赶进度,都是合理处置。注意答题时看清多选标记。

Q9. 关于消息队列的可靠性,下列说法正确的是?

单选题 · mid

  • A.队列天然不会丢失消息
  • B.持久化副本确认来保障← 正确答案
  • C.只要配置分区数量即可
  • D.消息可靠性全在生产者

答案:B。可靠性由磁盘持久化、多副本、生产者 ack、消费者手动提交共同保障。A 过于绝对,C 只提分区远远不够,D 忽略了队列和消费端的角色。

Q10. 秒杀场景下,消息队列削峰的最佳实践是?

单选题 · hard

  • A.前端限流加队列加异步落库← 正确答案
  • B.把队列当作唯一存储介质
  • C.所有请求同步返回处理结果
  • D.无限扩大队列容量不消费

答案:A。秒杀的正确姿势是组合拳:前端限流先挡掉一部分,队列削峰缓冲,后端异步落库处理。B 把队列当存储是错误的,C 同步返回违背削峰思想,D 只扩容不消费会让积压持续膨胀。