路由(Routing)

在前面的教程中,我们实现了一个简单的日志系统。可以把日志消息广播给多个接收者。

本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集。例如,我们只需要把严重的错误日志信息写入日志文件(存储到磁盘),但同时仍然把所有的日志信息输出到控制台中

绑定(Bindings)

前面的例子,我们已经创建过绑定(bindings),代码如下:

$exchange->publish($message, '');

绑定(binding)是指交换器(exchange)和队列(queue)的关系。可以简单理解为:这个队列(queue)对这个交换器(exchange)的消息感兴趣。

绑定的时候可以带上一个额外的routingkey参数。为了避免与basicpublish的参数混淆,我们把它叫做binding key。以下是如何创建一个带binding key的绑定。

$exchange->publish($message, $routeKey);

binding key的含义取决于交换器(exchange)的类型。我们之前使用过的fanout类型会忽略这个值。

Direct类型的交换器(exchange)

我们的日志系统广播所有的消息给所有的消费者(consumers)。我们打算扩展它,使其可以能够精确的过滤消息。例如我们也许值是希望当接收到一个严重的错误的时候才把消息写入磁盘,以免浪费磁盘空间。

我们使用的fanout类型的交换器(exchange)扩展性不够——它能做的仅仅是广播。

我们将会使用direct类型的交换器(exchange)来代替。路由的算法很简单——交换器将会对binding key和routing key进行精确匹配,从而确定消息该分发到哪个队列。

下图能够很好的描述这个场景:

在这个场景中,我们可以看到direct exchange X和两个队列绑定了。第一个队列使用orange作为binding key,第二个队列有两个绑定,一个使用black作为binding key,另外一个是green。

这样以来,当routing key为orange的消息发布到交换器(exchange),就会被路由到队列Q1。routing key为black或者green的消息就会路由到Q2。其他的所有消息都将会被丢弃。

多个绑定(Multiple bindings)

多个队列使用相同的binding key是合法的。我们的这个例子,我们可以添加一个X和Q1之间的绑定,使用blackbinding key。这样一来,direct交换器就和fanout交换器的行为一样,将会广播消息到所有匹配的队列。带有routing key为black的消息都会发送到Q1和Q2。

Emitting logs

我们将会发送消息到一个direct exchange,把日志级别作为routing key。这样子负责处理接收的脚本就可以选择它要处理的日志级别。我们先看看触发日志。

我们需要创建一个交换器(exchange):

$exchange->setName('direct_logs');

然后我们发送一则消息:

$exchange->publish($message, $severity);

我们先假设“severity”的值是info、warning、error中的一个。

订阅(Subscribing)

处理接收消息的方式和之前差不多,但是我们为每一个日志级别创建了一个新的绑定。

foreach ($severities as $item) {
$queue->bind($exchangeName, $item);
}

整合

emitlogdirect.py的代码:

<?php

/**
* PHP amqp(RabbitMQ) Demo-4
* @author yuansir &lt;yuansir@live.cn/yuansir-web.com>
*/
$severity = count($argv) > 2 ? $argv[1] : 'info';
$message = empty($argv[2]) ? 'Hello World!' : ' ' . $argv[2]; $connection = new AMQPConnection(array('host' => '127.0.0.1', 'port' => '5672', 'vhost' => '/', 'login' => 'guest', 'password' => 'guest'));
$connection->connect() or die("Cannot connect to the broker!\n"); $channel = new AMQPChannel($connection);
$exchange = new AMQPExchange($channel);
$exchange->setName('direct_logs');
$exchange->setType(AMQP_EX_TYPE_DIRECT);
$exchange->declare(); $exchange->publish($message, $severity);
var_dump("[x] Sent $message"); $connection->disconnect();

receivelogsdirect.py的代码:

<?php

/**
* PHP amqp(RabbitMQ) Demo-4
* @author yuansir &lt;yuansir@live.cn/yuansir-web.com>
*/
$exchangeName = 'direct_logs'; $connection = new AMQPConnection(array('host' => '127.0.0.1', 'port' => '5672', 'vhost' => '/', 'login' => 'guest', 'password' => 'guest'));
$connection->connect() or die("Cannot connect to the broker!\n");
$channel = new AMQPChannel($connection);
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
$exchange->setType(AMQP_EX_TYPE_DIRECT);
$exchange->declare();
$queue = new AMQPQueue($channel);
$queue->setFlags(AMQP_EXCLUSIVE);
$queue->declare(); $severities = $argv;
$file = $severities[0];
unset($severities[0]);
if (!$severities) {
var_dump("Usage:$file [info] [warning] [error]");
exit();
} else {
foreach ($severities as $item) {
$queue->bind($exchangeName, $item);
}
} var_dump('[*] Waiting for messages. To exit press CTRL+C');
while (TRUE) {
$queue->consume('callback');
}
$connection->disconnect(); function callback($envelope, $queue) {
$msg = $envelope->getBody();
var_dump('[x]' . $envelope->getRoutingKey() . ':' . $msg);
$queue->nack($envelope->getDeliveryTag());
}

如果你希望只是保存warning和error级别的日志到磁盘,只需要打开控制台并输入:

$ php receive_logs_direct.php warning error &gt; logs_from_rabbit.log

如果你希望所有的日志信息都输出到屏幕中,打开一个新的终端,然后输入:

$ php receive_logs_direct.php info warning error
[*] Waiting for logs. To exit press CTRL+C

如果要触发一个error级别的日志,只需要输入:

$ php emit_log_direct.php error "Run. Run. Or it will explode."
[x] Sent 'error':'Run. Run. Or it will explode.'

转载自Ryan是菜鸟 | LNMP技术栈笔记

RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)的更多相关文章

  1. RabbitMQ 入门教程(PHP版) 第四部分:路由(Routing)

    路由(Routing) 在前面的第三部分教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重 ...

  2. RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)

    发布/订阅 在上篇教程中,我们搭建了一个工作队列.每个任务之分发给一个工作者(worker).在本篇教程中,我们要做的之前完全不一样——分发一个消息给多个消费者(consumers).这种模式被称为“ ...

  3. RabbitMQ官方中文入门教程(PHP版) 第二部分:工作队列(Work queues)

    工作队列 在第一篇教程中,我们已经写了一个从已知队列中发送和获取消息的程序.在这篇教程中,我们将创建一个工作队列(Work Queue),它会发送一些耗时的任务给多个工作者(Works ). 工作队列 ...

  4. RabbitMQ官方中文入门教程(PHP版) 第一部分:Hello World

    RabbitMQ是一个消息代理.它的核心原理非常简单:接收和发送消息.你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处.在这个比喻中,RabbitMQ是一个邮箱.邮局.邮 ...

  5. ActiveReports 报表控件官方中文入门教程 (1)-安装、激活以及产品资源

    本系列文章主要是面向初次接触 ActiveReports 产品的用户,可以帮助您在三天之内轻松的掌握ActiveReports控件的基本使用方法,包括安装.激活.创建报表.绑定数据源以及发布等内容.本 ...

  6. ActiveReports 报表控件官方中文入门教程 (3)-如何选择页面报表和区域报表

    本篇文章将介绍区域报表和页面报表的常见使用场景.区别和选择报表类型的一些建议,两种报表的模板设计.数据源(设计时和运行时)设置.和浏览报表的区别. ActiveReports 报表控件官方中文入门教程 ...

  7. ActiveReports 报表控件官方中文入门教程 (2)-创建、数据源、浏览以及发布

    本篇文章将阐述首次使用 ActiveReports 报表控件 的方法,包括添加报表文件.绑定数据源以及如何发布报表等内容. ActiveReports 报表控件官方中文入门教程 (1)-安装.激活以及 ...

  8. 转载:《TypeScript 中文入门教程》

    缘由 事情是这样的,我想搜索 TypeScript 中文教程,结果在 https://www.baidu.com , https://cn.bing.com ,上都找不到官方的翻译,也没有一个像样的翻 ...

  9. ActiveReports 报表控件官方中文新手教程 (1)-安装、激活以及产品资源

     本系列文章主要是面向初次接触 ActiveReports 产品的用户,能够帮助您在三天之内轻松的掌握ActiveReports控件的基本用法,包含安装.激活.创建报表.绑定数据源以及公布等内容. ...

随机推荐

  1. RabbitMQ与Redis队列对比

    本文仅针对RabbitMQ与Redis做队列应用时的情况进行对比具体采用什么方式实现,还需要取决于系统的实际需求 简要介绍 RabbitMQ RabbitMQ是实现AMQP(高级消息队列协议)的消息中 ...

  2. MMORPG大型游戏设计与开发(客户端架构 part5 of vegine)

    客户端异常捕获,是一件必然的事情,特别是在开发的时候就更需要这些有利于找出问题原因的捷径.区别于服务器的是,客户端基本上是以界面为主,你很难在正常运行程序的情况下进行一些输出的监视,如一些日志的记录. ...

  3. 【HTML5】使用多媒体

    HTML5 支持直接在浏览器中播放音频和视频文件,不需要使用Abode Flash这样的插件. 1. 使用 video 元素 可以用video 元素在网页里嵌入视频内容. 其基本用法如下: <! ...

  4. 【温故而知新-Javascript】使用canvas元素(第一部分)

    1. 开始使用 canvas 元素 canvas 元素非常简单,这是指它所有的功能都体现在一个JavaScript对象上,因此该元素本身只有两个属性:width 和 height. canvas 元素 ...

  5. UART to Serial Terminal(转载)

    前一篇<UART Explained>介绍了UART的基本信息,重点分析了UART的信号.本文摘录的文章则重点介绍了波特率(Baud Rate)相关的内容,波特率越高,传输速度越快,但实际 ...

  6. Xbox Live会员身份:银会员和金会员

    推出Xbox360之后,微软重新设计了Xbox Live平台.新设计建立了两个等级的Xbox Live会员身份:银会员和金会员.

  7. 0e开头md5汇总

    PHP在处理哈希字符串时,会利用"!="或"=="来对哈希值进行比较,它把每一个以"0E"开头的哈希值都解释为0,所以如果两个不同的密码经过 ...

  8. Android ART运行时与Dalvik虚拟机

    这几天在做一个项目时需要在Android中使用OSGi框架(Apache Felix),于是在一个android 4.4.2 版本系统的某品牌的平板上实验. 实验内容很简单:把felix包里的feli ...

  9. JAVA常用的XML解析方法

    转并总结自(java xml) JAVA常用的解析xml的方法有四种,分别是DOM,JAX,JDOM,DOM4j xml文件 <?xml version="1.0" enco ...

  10. Castle IOC容器与Spring.NET配置之比较

    我本人对于Spring.NET并不了解,本文只是通过一个简单的例子来比较一下两者配置之间的区别.在Castle IOC容器中,提出了自动装配(Auto-Wiring)的概念,即由容器自动管理组件之间的 ...