[TOC] #### 1. 前言 --- 上一讲我们知道了 Exchange 负责把消息分拣到不同的队列,但分拣需要规则 这一讲我们来看最简单、最常用的规则:Direct Exchange(精确匹配) #### 2. 为什么消息需要精准投递 --- 假设你做了一个日志系统,有三种级别的日志: + error:错误日志,需要立刻告警 + warning:警告日志,记录但不告警 + info:普通日志,只做记录 你希望: + error:日志发到告警队列,触发短信通知 + warning:日志发到监控队列,做统计分析 + info:日志发到日志队列,存起来就行 每条消息要精确地送到对应的队列,不能送错,这就是 Direct Exchange 的场景 #### 3. 精准投递代码示例 --- Direct Exchange 的规则很简单: + Producer 发消息的时候,带一个路由标识(比如 error) + Queue 绑定 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.声明 Direct 类型的 Exchange $channel->exchange_declare('log_exchange', 'direct', false, true, false); // 2.声明三个队列 $channel->queue_declare('error_queue', false, true, false, false); $channel->queue_declare('warning_queue', false, true, false, false); $channel->queue_declare('info_queue', false, true, false, false); // 3.将队列绑定交换机:队列名 + Exchange名 + 路由标识 $channel->queue_bind('error_queue', 'log_exchange', 'error'); $channel->queue_bind('warning_queue', 'log_exchange', 'warning'); $channel->queue_bind('info_queue', 'log_exchange', 'info'); // 4.Producer 发送不同级别的日志,第二个参数是 Exchange 名字,第三个参数就是路由标识 # 发一条 error 日志 $message = new AMQPMessage('数据库连接失败'); $channel->basic_publish($message, 'log_exchange', 'error'); # 发一条 info 日志 $message = new AMQPMessage('用户登录成功'); $channel->basic_publish($message, 'log_exchange', 'info'); echo "消息已发送\n"; $channel->close(); $connection->close(); ``` 绑定之后,消息的去向就确定了: ```plaintext 路由标识为 error → error_queue 路由标识为 warning → warning_queue 路由标识为 info → info_queue ``` Consumer:各自消费各自的队列,各取所需,互不影响 + 告警系统消费 error_queue + 监控系统消费 warning_queue + 日志系统消费 info_queue 同一个队列可以绑定多个路由标识: ```php $channel->queue_bind('alert_queue', 'log_exchange', 'error'); $channel->queue_bind('alert_queue', 'log_exchange', 'warning'); ``` 这样 `error` 和 `warning` 的消息都会发到 `alert_queue` 什么场景需要绑定多个路由标识 ?告警系统同时关心错误和警告,但不关心普通日志 #### 4. 本文小结 --- Direct Exchange 的核心规则:消息的路由标识和队列的路由标识完全一致,才会投递 适用场景: + 消息类型明确,可以按类型分流 + 不同类型的消息需要不同的系统处理 + 比如日志分级、订单状态分流、不同业务线的消息分发 记住一句话:Direct Exchange 就是精确匹配,路由标识一样才投递 下一讲,我们来看另一种场景:一条消息需要让多个系统同时收到,怎么做?