RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
来源:互联网 发布:淘宝电子凭证是什么 编辑:程序博客网 时间:2024/05/06 00:19
版权声明:本文为博主原创文章,未经博主允许不得转载。
目录(?)[+]
路由(Routing)
在前面的教程中,我们实现了一个简单的日志系统。可以把日志消息广播给多个接收者。
本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集。例如,我们只需要把严重的错误日志信息写入日志文件(存储到磁盘),但同时仍然把所有的日志信息输出到控制台中
绑定(Bindings)
前面的例子,我们已经创建过绑定(bindings),代码如下:
1
$exchange
->publish(
$message
,
''
);
绑定(binding)是指交换器(exchange)和队列(queue)的关系。可以简单理解为:这个队列(queue)对这个交换器(exchange)的消息感兴趣。
绑定的时候可以带上一个额外的routing_key参数。为了避免与basic_publish的参数混淆,我们把它叫做binding key。以下是如何创建一个带binding key的绑定。
1
$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):
1
$exchange
->setName(
'direct_logs'
);
然后我们发送一则消息:
1
$exchange
->publish(
$message
,
$severity
);
我们先假设“severity”的值是info、warning、error中的一个。
订阅(Subscribing)
处理接收消息的方式和之前差不多,但是我们为每一个日志级别创建了一个新的绑定。
1
foreach
(
$severities
as
$item
) {
2
$queue
->bind(
$exchangeName
,
$item
);
3
}
整合
emit_log_direct.py的代码:
01
<?php
02
03
/**
04
* PHP amqp(RabbitMQ) Demo-4
05
* @author yuansir <yuansir@live.cn/yuansir-web.com>
06
*/
07
$severity
=
count
(
$argv
) > 2 ?
$argv
[1] :
'info'
;
08
$message
=
empty
(
$argv
[2]) ?
'Hello World!'
:
' '
.
$argv
[2];
09
10
$connection
=
new
AMQPConnection(
array
(
'host'
=>
'127.0.0.1'
,
'port'
=>
'5672'
,
'vhost'
=>
'/'
,
'login'
=>
'guest'
,
'password'
=>
'guest'
));
11
$connection
->connect()
or
die
(
"Cannot connect to the broker!\n"
);
12
13
$channel
=
new
AMQPChannel(
$connection
);
14
$exchange
=
new
AMQPExchange(
$channel
);
15
$exchange
->setName(
'direct_logs'
);
16
$exchange
->setType(AMQP_EX_TYPE_DIRECT);
17
$exchange
->
declare
();
18
19
$exchange
->publish(
$message
,
$severity
);
20
var_dump(
"[x] Sent $message"
);
21
22
$connection
->disconnect();
receive_logs_direct.py的代码:
01
<?php
02
03
/**
04
* PHP amqp(RabbitMQ) Demo-4
05
* @author yuansir <yuansir@live.cn/yuansir-web.com>
06
*/
07
$exchangeName
=
'direct_logs'
;
08
09
$connection
=
new
AMQPConnection(
array
(
'host'
=>
'127.0.0.1'
,
'port'
=>
'5672'
,
'vhost'
=>
'/'
,
'login'
=>
'guest'
,
'password'
=>
'guest'
));
10
$connection
->connect()
or
die
(
"Cannot connect to the broker!\n"
);
11
$channel
=
new
AMQPChannel(
$connection
);
12
$exchange
=
new
AMQPExchange(
$channel
);
13
$exchange
->setName(
$exchangeName
);
14
$exchange
->setType(AMQP_EX_TYPE_DIRECT);
15
$exchange
->
declare
();
16
$queue
=
new
AMQPQueue(
$channel
);
17
$queue
->setFlags(AMQP_EXCLUSIVE);
18
$queue
->
declare
();
19
20
$severities
=
$argv
;
21
$file
=
$severities
[0];
22
unset(
$severities
[0]);
23
if
(!
$severities
) {
24
var_dump(
"Usage:$file [info] [warning] [error]"
);
25
exit
();
26
}
else
{
27
foreach
(
$severities
as
$item
) {
28
$queue
->bind(
$exchangeName
,
$item
);
29
}
30
}
31
32
var_dump(
'[*] Waiting for messages. To exit press CTRL+C'
);
33
while
(TRUE) {
34
$queue
->consume(
'callback'
);
35
}
36
$connection
->disconnect();
37
38
function
callback(
$envelope
,
$queue
) {
39
$msg
=
$envelope
->getBody();
40
var_dump(
'[x]'
.
$envelope
->getRoutingKey() .
':'
.
$msg
);
41
$queue
->nack(
$envelope
->getDeliveryTag());
42
}
如果你希望只是保存warning和error级别的日志到磁盘,只需要打开控制台并输入:
1
$ php receive_logs_direct.php warning error &
gt
; logs_from_rabbit.log
如果你希望所有的日志信息都输出到屏幕中,打开一个新的终端,然后输入:
1
$ php receive_logs_direct.php info warning error
2
[*] Waiting
for
logs. To
exit
press CTRL+C
如果要触发一个error级别的日志,只需要输入:
1
$ php emit_log_direct.php error
"Run. Run. Or it will explode."
2
[x] Sent
'error'
:
'Run. Run. Or it will explode.'
- RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
- RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
- RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
- RabbitMQ官方中文入门教程(PHP版) 第一部分:Hello World
- RabbitMQ官方中文入门教程(PHP版) 第一部分:Hello World
- RabbitMQ官方中文入门教程(PHP版) 第一部分:Hello World
- RabbitMQ官方中文入门教程(PHP版) 第二部分:工作队列(Work queues)
- RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)
- RabbitMQ官方中文入门教程(PHP版) 第二部分:工作队列(Work queues)
- RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)
- RabbitMQ官方中文入门教程(PHP版) 第二部分:工作队列(Work queues)
- RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)
- RabbitMQ入门教程(六):路由选择Routing
- RabbitMQ(PHP版) 中文入门教程第一部分:Hello World
- rabbitmq(四) Routing(路由)
- RabbitMQ Routing(路由选择)
- RabbitMQ路由Routing
- RabbitMQ (四) 路由选择 (Routing)
- RabbitMQ官方中文入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)
- TCP聊天室
- Activiti学习——生成历史流程跟踪图
- runtime运行机制
- cocoapods questions I met when update to OS10.11
- RabbitMQ官方中文入门教程(PHP版) 第四部分:路由(Routing)
- 7zip命令
- App Store App申请审核加速
- JEECG-P3开发专题 - 开发环境搭建入门
- Android中SnackBar的简单使用
- JavaScript中为空判断
- 移动互联网敏捷开发流程
- DHCP原理
- 地图和地理空间革命:地理学大规模开放在线课堂(MOOC)