Files
autumn-recruitment/04.MQ/rabbitmq/Exchange 路由机制_test.md

154 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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/推拉结合消费模式]]