[TOC] #### 1. 前言 --- 从这一讲开始,我们进入 Exchange 交换机 在讲四种 Exchange 类型之前,我们先搞清楚一个问题:为什么 RabbitMQ 需要 Exchange ? #### 2. 没有 Exchange 会怎样 --- 假设你做了一个电商系统,有三个队列: + `sms_queue`:短信系统在消费 + `email_queue`:邮件系统在消费 + `logistics_queue`:物流系统在消费 用户下单之后,Producer 需要把消息发到这三个队列里,代码大概这样: ```php $channel->basic_publish($message, '', 'sms_queue'); $channel->basic_publish($message, '', 'email_queue'); $channel->basic_publish($message, '', 'logistics_queue'); ``` Producer 直接往三个队列里发消息,看起来能用,但有几个问题: 问题一:Producer 和队列绑死了,Producer 必须知道有哪些队列,必须一个一个发 + 以后加一个积分系统,Producer 代码得改,加一个优惠券系统,还得改 问题二:发消息的逻辑变复杂了,每加一个下游系统,Producer 就多一行代码 + 10 个系统就要发 10 次,Producer 本来只管「发消息」,现在还要管「发给谁」 问题三:灵活性差 + 有些消息需要发给所有队列,有些只需要发给部分队列 + 如果 Producer 直接往队列里发,这些逻辑都得写在 Producer 代码里 #### 3. Exchange 的作用 --- Exchange 就是为了解决这些问题,有了 Exchange 之后,Producer 不再直接往队列里发消息 它只把消息发给 Exchange: ```php $channel->basic_publish($message, 'order_exchange', 'order.created'); ``` 然后由 Exchange 根据规则,把消息路由到对应的队列,Producer 只管发给 Exchange,不关心消息去了哪些队列 队列的增减、路由的调整,都不需要改 Producer 的代码 #### 4. Exchange 的核心逻辑 --- Exchange 做的事情很简单,就两步: + 接收 Producer 发来的消息 + 根据规则,把消息投递到一个或多个 Queue 至于「规则」是什么,取决于 Exchange 的类型,RabbitMQ 有四种 Exchange: | 类型 | 规则 | | ------------ | ------------ | | Direct | 精确匹配,消息只发给指定的队列 | | Fanout | 广播,消息发给所有绑定的队列 | | Topic | 通配符匹配,按规则批量投递 | | Headers | 根据消息头属性匹配 | 这四种类型我们后面四讲会一个一个讲,现在只需要记住:Exchange 负责分拣,Producer 不用管 #### 5. 回到开头的问题 --- 没有 Exchange 的时候,Producer 要一个一个队列发消息,有了 Exchange 之后: ```plaintext Producer → Exchange → sms_queue → sms_queue → email_queue → logistics_queue → points_queue (新加的,Producer 代码不用改) ``` Producer 只发一次,Exchange 负责分发,加新队列 ?在 Exchange 上绑定一下就行,Producer 完全不用动 这就是 Exchange 存在的意义:把「发消息」和「投递消息」分开 #### 6. 本文小结 --- Exchange 是 Producer 和 Queue 之间的中间人 Producer 把消息发给 Exchange,Exchange 根据规则投递到 Queue 这样做的好处: + Producer 不需要知道有哪些队列 + 队列可以随意增减,Producer 代码不用改 + 路由逻辑集中在 Exchange,方便管理和调整 核心一句话:Producer 管「发」,Exchange 管「送」 下一讲,我们来看第一种 Exchange 类型:Direct Exchange,它解决的是「精准投递」的问题