7.9 KiB
tags, create time
| tags | create time | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
2026-08-09 12:00 |
Exchange 路由机制_测试题
概述
本测试覆盖 RabbitMQ 四种内置 Exchange 类型(Direct、Fanout、Topic、Headers)以及延迟交换插件和死信交换机的特性。共 10 道题:6 道选择题、3 道填空题、1 道简答题。
一、选择题(6道,由浅入深)
难度阶梯: Q1-Q2 基础概念 → Q3-Q4 核心原理 → Q5-Q6 深入应用/边界场景
Q1(基础)— 考察定义层面
以下哪种 Exchange 类型完全忽略 routing key,将消息投递到所有绑定到该 Exchange 的 Queue?
A. Direct Exchange B. Topic Exchange C. Fanout Exchange D. Headers Exchange
Q2(基础)— 考察行为判断
在 Topic Exchange 中,binding key 为 *.error.*,以下哪个 routing key 能够匹配?
A. order.create
B. system.error.disk.full
C. app.error
D. error.log
Q3(进阶)— 考察核心原理
关于 Topic Exchange 的通配符规则,以下哪项描述是正确的?
A. * 匹配零个或多个词,# 匹配恰好一个词
B. * 和 # 都匹配任意数量的词
C. * 匹配恰好一个词(以点号分隔),# 匹配零个或多个词
D. * 只能用于 binding key 的前缀位置
Q4(进阶)— 考察对比辨析
以下哪种 Exchange 类型的性能最差且官方明确标注"不推荐在生产中使用"?
A. Direct Exchange B. Fanout Exchange C. Topic Exchange D. Headers Exchange
Q5(深入)— 考察场景推理
某系统需要实现"超时未支付自动取消订单"的功能,要求在订单创建后精确等待指定时长(如 30 分钟)再发送取消消息。以下哪种方案最合适?
A. 使用 Direct Exchange + 定时任务轮询检查 B. 安装 x-delayed-message 插件,声明延迟 Exchange 并在消息头设置 x-delay C. 使用 Redis ZSet 定时弹出功能 D. 在消费者端 sleep 30 分钟后再处理
Q6(深入)— 考察源码级别细节
在使用 x-delayed-message 插件时,声明延迟 Exchange 的一个必要参数是 x-delayed-type,它的作用是什么?
A. 指定 Exchange 的名称 B. 指定延迟到期后内部转发消息所使用的 Exchange 类型 C. 指定消息的最大延迟时间 D. 指定 Exchange 是否持久化
二、填空题(3道)
F1 — 填空
Direct Exchange 的路由规则是完全匹配:routing key 必须与 Queue 绑定到 Exchange 时的 binding key ______ ,消息才会被投递。
提示: 一个字概括这个关系。
F2 — 填空
Topic Exchange 中,binding key 为 # 时可以匹配 ______ 路由(即所有消息)。
提示: 井号匹配的语义是什么?
F3 — 填空
DLX(Dead Letter Exchange)本质上也是一个普通 Exchange,只是通过队列属性间接触发。当队列中的消息 TTL 过期或被 nack 且不重新入队或队列长度限制已满时,会被重新路由到 DLX。DLX 可以配置自己的 binding key(即 x-dead-letter-______)来控制死信消息的去向。
提示: 这是 DLX 路由时使用的 key 属性名。
三、简答题(1道)
S1
你正在为一个大型电商平台设计消息路由系统,有以下业务需求:
- 用户下单成功后,需要通知库存系统扣减库存、物流系统生成运单、优惠券系统退还优惠券
- 这些下游服务可能随时增减,不能硬编码 routing key
- 日志系统需要接收所有级别的日志消息(info/warn/error),但运维人员只想订阅 error 和 warn
- 部分非关键通知(如用户注册邮件)可以在 10 分钟后发送
- 失败的消息需要有归档通道
请设计一套 Exchange 和 routing key 的命名规范及架构方案,回答以下问题:
- 每种业务场景选择什么 Exchange 类型?
- routing key 的命名规范建议是什么?
- 如何满足"服务动态增减"的需求?
答题框架提示:
- 逐一对应需求分析最优 Exchange 选型
- 提出层级化的 routing key 命名策略
- 说明如何通过 Topic Exchange 的通配符能力实现解耦
参考答案与解析
选择题答案
| 题号 | 正确答案 | 解析 |
|---|---|---|
| Q1 | C | Fanout Exchange 忽略 routing key,将消息广播投递到所有绑定到该 Exchange 的 Queue。典型场景:事件广播、配置刷新、缓存失效通知。 |
| Q2 | B | *.error.* 通配符匹配规则:* 匹配恰好一个词。system.error.disk.full 有三段中间一段是 error,符合 .error.(第一段任何、第二段 error、第三段任何)。A 只有一段;C 只有两段缺第三段;D 结构完全不对。 |
| Q3 | C | *(星号)匹配恰好一个词(以点号分隔),#(井号)匹配零个或多个词。例如 order.create 匹配 # 也匹配 *.create,但不匹配 .pay.。这是面试常考点。 |
| Q4 | D | Headers Exchange 通过检查消息的 headers 属性(key-value 对)来决定路由,性能较差且灵活性不如 Topic Exchange,官方文档明确标注"不推荐在生产中使用"。应优先选择 Topic Exchange。 |
| Q5 | B | x-delayed-message 插件是最直接可靠的延迟消息方案。RabbitMQ 原生不支持延迟消息,常见替代方案有定时任务轮询(复杂)、Redis ZSet(增加外部依赖)等,但在高可靠性场景中都不如插件方案简洁可靠。 |
| Q6 | B | x-delayed-type 指定延迟到期后内部转发消息所使用的 Exchange 类型(通常为 direct)。这是声明延迟 Exchange 的必要参数,告诉插件消息延期后应该用什么路由规则进行转发。 |
填空题答案
| 题号 | 答案 | 解析 |
|---|---|---|
| F1 | 一致(或相同) | Direct Exchange 使用完全匹配原则:routing key 必须与 binding key 完全一致。支持一对一或一对多投递(多个 Queue 绑定了相同的 binding key)。这是最常用也最可预测的路由方式。 |
| F2 | 全部(或所有) | # 匹配零个或多个词,因此 # 作为 binding key 可以匹配所有的 routing key。在 Topic Exchange 中常用于"全量订阅"的场景。 |
| F3 | routing-key | DLX 可以配置 x-dead-letter-routing-key 属性来控制死信消息转发到 DLX 时使用的 routing key。如果未显式指定则默认使用消息原先进入队列时的 routing key。 |
简答题参考答案
S1:参考答案要点:
- 下单通知:使用 Topic Exchange。routing key 格式
order.{event_type}(如 order.create、order.pay)。库存、物流、优惠券分别 binding 不同的 key 前缀。这样新增下游服务只需声明 binding 即可,无需修改生产者代码——完美支持动态增减。 - 日志分级收集:同样使用 Topic Exchange,routing key 格式
{service}.log.{level}(如 user-service.log.error)。运维绑定 binding key*.log.error和*.log.warn,其他组件绑定更具体的 level。 - 延迟通知:安装 x-delayed-message 插件,声明一个 delayed.exchange(x-delayed-message 类型),所有非关键通知统一发到这里并设置 x-delay header(单位毫秒)。
- 死信归档:每个关键业务的 Queue 都配置 x-dead-letter-exchange 指向统一的 dead-letter-exchange(Direct 类型),死信 routing key 格式
{original_queue}.dead,方便定位和归档。 - routing key 命名规范建议采用层级化命名:
{domain}.{entity}.{action}如order.create.success、user.register.email。Top-level 表示业务域,便于按域分组路由。
评分标准:答出任意 2 个要点即可得满分;完全正确需覆盖 Exchange 选型、命名规范、动态扩展方案和死信设计四个维度。