[TOC] #### 1. 前言 --- 上一讲我们学了 `Direct Exchange`,消息按标签精确投递到指定队列 但有些场景,你需要的不是「精确」,而是「广播」 为什么一条消息需要让多个系统同时收到 ? 假设你做了一个用户注册功能,用户注册成功之后,需要同时做三件事: + 发送欢迎邮件 + 发放新人优惠券 + 记录到数据仓库做分析 ```php $channel->basic_publish($message, 'user_exchange', 'email'); $channel->basic_publish($message, 'user_exchange', 'coupon'); $channel->basic_publish($message, 'user_exchange', 'analytics'); ``` 每加一个系统,Producer 就多一行代码,而且 Producer 必须知道有哪些系统需要这条消息 Producer 又变成了「调度中心」 #### 2. Fanout Exchange --- Fanout Exchange 的规则非常简单:不管标记是什么,所有绑定到这个 Exchange 的队列都能收到消息 Producer 只发一次,Exchange 自动广播给所有绑定的队列: ```php $channel->basic_publish($message, 'user_exchange', ''); ``` 就像你在公司群里发了一条通知:「明天下午三点开会」,群里所有人都能看到,你不需要一个一个私聊 代码示例: ```php require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connection\AMQPStreamConnection; use PhpAmqpLib\Message\AMQPMessage; $connection = new AMQPStreamConnection('192.168.3.20', 5672, 'admin', 'admin123'); $channel = $connection->channel(); // 1.声明 Fanout 类型的 Exchange $channel->exchange_declare('user_exchange', 'fanout', false, true, false); // 2.声明三个队列 $channel->queue_declare('email_queue', false, true, false, false); $channel->queue_declare('coupon_queue', false, true, false, false); $channel->queue_declare('analytics_queue', false, true, false, false); // 3.绑定到 Exchange(Fanout 不需要指定标记,直接绑就行) $channel->queue_bind('email_queue', 'user_exchange'); $channel->queue_bind('coupon_queue', 'user_exchange'); $channel->queue_bind('analytics_queue', 'user_exchange'); // 4.Producer 发消息,消息发出去之后,三个队列都会收到一份 $message = new AMQPMessage(json_encode(['user_id' => 1, 'name' => 'liang'])); $channel->basic_publish($message, 'user_exchange', ''); echo "消息已发送\n"; $channel->close(); $connection->close(); ``` #### 3. Fanout 和 Direct 的区别 --- | 对比项 | Direct | Fanout | | ------------ | ------------ | ------------ | | 匹配方式 | 精确匹配标记 | 不匹配,全部广播 | | Producer 需要知道什么 | 消息应该带什么标记 | 不需要,发一次就行 | | 适用场景 | 按类型分流 | 一条消息多人消费 | Direct 是「你点名要谁,就发给谁」,Fanout 是「你喊一嗓子,所有人都听到」 Fanout 的一个注意点: + Fanout 广播的是 一模一样的消息,所有队列收到的内容都一样 + 如果需要对不同队列发不同的内容,Fanout 不适合,还是得用 Direct 或者其它方式 #### 4. 本文小结 --- Fanout Exchange 的核心规则:消息广播给所有绑定到这个 Exchange 的队列,不看标记 适用场景: + 一条消息需要多个系统同时处理 + 各系统处理的逻辑不同,但数据来源相同 + 比如用户注册后同时通知邮件、优惠券、数据分析等系统 记住一句话:Fanout 就是广播,一发所有人收到 下一讲,我们来看一种更灵活的匹配方式:Topic Exchange,它能按规则批量匹配