--- tags: [test/review, mq, rabbitmq, exchange-routing, direct-exchange, fanout-exchange, topic-exchange, headers-exchange, delay-exchange] 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 你正在为一个大型电商平台设计消息路由系统,有以下业务需求: 1. 用户下单成功后,需要通知库存系统扣减库存、物流系统生成运单、优惠券系统退还优惠券 2. 这些下游服务可能随时增减,不能硬编码 routing key 3. 日志系统需要接收所有级别的日志消息(info/warn/error),但运维人员只想订阅 error 和 warn 4. 部分非关键通知(如用户注册邮件)可以在 10 分钟后发送 5. 失败的消息需要有归档通道 请设计一套 Exchange 和 routing key 的命名规范及架构方案,回答以下问题: 1. 每种业务场景选择什么 Exchange 类型? 2. routing key 的命名规范建议是什么? 3. 如何满足"服务动态增减"的需求? > **答题框架提示**: 1. 逐一对应需求分析最优 Exchange 选型 2. 提出层级化的 routing key 命名策略 3. 说明如何通过 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:**参考答案要点**: 1. 下单通知:使用 Topic Exchange。routing key 格式 `order.{event_type}`(如 order.create、order.pay)。库存、物流、优惠券分别 binding 不同的 key 前缀。这样新增下游服务只需声明 binding 即可,无需修改生产者代码——完美支持动态增减。 2. 日志分级收集:同样使用 Topic Exchange,routing key 格式 `{service}.log.{level}`(如 user-service.log.error)。运维绑定 binding key `*.log.error` 和 `*.log.warn`,其他组件绑定更具体的 level。 3. 延迟通知:安装 x-delayed-message 插件,声明一个 delayed.exchange(x-delayed-message 类型),所有非关键通知统一发到这里并设置 x-delay header(单位毫秒)。 4. 死信归档:每个关键业务的 Queue 都配置 x-dead-letter-exchange 指向统一的 dead-letter-exchange(Direct 类型),死信 routing key 格式 `{original_queue}.dead`,方便定位和归档。 5. routing key 命名规范建议采用层级化命名:`{domain}.{entity}.{action}` 如 `order.create.success`、`user.register.email`。Top-level 表示业务域,便于按域分组路由。 **评分标准**:答出任意 2 个要点即可得满分;完全正确需覆盖 Exchange 选型、命名规范、动态扩展方案和死信设计四个维度。 ## 关联笔记 - [[04.MQ/rabbitmq/消息持久化与可靠性投递]] - [[04.MQ/rabbitmq/ACK 确认与死信队列]] - [[04.MQ/rabbitmq/推拉结合消费模式]]