搜尋
首頁php教程php手册译-PHP rabbitMQ Tutorial-5

Topics (usingphp-amqplib) In theprevious tutorialwe improved our logging system. Instead of using afanoutexchange only capable of dummy broadcasting, we used adirect one, and gained a possibility of selectively receiving the logs. 上一节,

Topics

(using php-amqplib)

 

In the previous tutorial we improved our logging system. Instead of using a fanout exchange only capable of dummy broadcasting, we used a direct one, and gained a possibility of selectively receiving the logs.

上一节,我们改进了日志系统。取代了fanout交换器仅仅会傻乎乎的广播,我们使用了定向交换器,使得选择性接收消息成为可能。

Although using the direct exchange improved our system, it still has limitations - it can't do routing based on multiple criteria.

尽管使用定向交换器改善了我们的系统,但它仍有局限性——不能基于多重条件进行路由。

In our logging system we might want to subscribe to not only logs based on severity, but also based on the source which emitted the log. You might know this concept from the syslog unix tool, which routes logs based on both severity (info/warn/crit...) and facility (auth/cron/kern...).

在日志系统中,我们可能想不仅订阅基于严重等级的内容,而且订阅基于消息发布来源的内容。你可以从syslog unix工具中得知这个概念——基于严重性和设备路由日志。

That would give us a lot of flexibility - we may want to listen to just critical errors coming from 'cron' but also all logs from 'kern'.

那会给我们带来很大的灵活性——我们可能想只是收听来自cron的致命错误和来自kern的所有消息。

To implement that in our logging system we need to learn about a more complex topic exchange.

为了在我们的日志系统上实现这种灵活性,我们需要学习一下更为复杂一些的topic交换器。

Topic exchange

Messages sent to a topic exchange can't have an arbitrary routing_key - it must be a list of words, delimited by dots. The words can be anything, but usually they specify some features connected to the message. A few valid routing key examples: "stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit". There can be as many words in the routing key as you like, up to the limit of 255 bytes.

发送到topic交换器的消息不能给一个任意的routing_key——它必须是一个由逗号分隔的单词列表。

The binding key must also be in the same form. The logic behind the topic exchange is similar to a direct one - a message sent with a particular routing key will be delivered to all the queues that are bound with a matching binding key. However there are two important special cases for binding keys:

binding key也必须是同样的格式。topic交换器背后的逻辑和定向交换器类似——带有特定routing key的消息会被派送到所有捆绑了与routing key相匹配的binding key的队列。

  • * (star) can substitute for exactly one word.
  • *(星号)可以代表一个单词
  • # (hash) can substitute for zero or more words.
  • #(井号)可以代表零个或多个单词

It's easiest to explain this in an example:

译-PHP rabbitMQ Tutorial-5

In this example, we're going to send messages which all describe animals. The messages will be sent with a routing key that consists of three words (two dots). The first word in the routing key will describe speed, second a colour and third a species: "..".

这个例子中,我们将发送所有描述动物的消息。发送时,这些消息带有由三个单词(两个点号分隔)组成的routing key.其中起一个单词用来表述速度,第二个用来表示颜色,最后一个用来表示种类:".."

We created three bindings: Q1 is bound with binding key "*.orange.*" and Q2 with "*.*.rabbit" and "lazy.#".

创建三个捆绑:用 "*.orange.*" 来绑定Q1,用 "*.*.rabbit" 和"lazy.#"来绑定Q2.

These bindings can be summarised as:

这几个捆绑可以概括为:

  • Q1 is interested in all the orange animals.
  • Q1喜欢所有橙色的动物
  • Q2 wants to hear everything about rabbits, and everything about lazy animals.
  • Q2想知道所有关于兔子和懒惰动物的事情

A message with a routing key set to "quick.orange.rabbit" will be delivered to both queues. Message "lazy.orange.elephant" also will go to both of them. On the other hand "quick.orange.fox" will only go to the first queue, and "lazy.brown.fox" only to the second. "lazy.pink.rabbit" will be delivered to the second queue only once, even though it matches two bindings. "quick.brown.fox" doesn't match any binding so it will be discarded.

这两个队列都会接收到routing key设置成"quick.orange.rabbit"的消息。设置成"lazy.orange.elephant"的也一样。

但"quick.orange.fox"仅仅会进入第一个队列,而"lazy.brown.fox"则仅会进入第二个队列。"lazy.pink.rabbit"仅仅会进入到第二个队列一次,虽然它可以匹配到两个困难规则。由于"quick.brown.fox"和谁都匹配不上,所以会被丢弃。

What happens if we break our contract and send a message with one or four words, like "orange" or "quick.orange.male.rabbit"? Well, these messages won't match any bindings and will be lost.

要是打破了我们的约束会怎样?比如,发送带有一个或是四个单词的,像"orange"或"quick.orange.male.rabbit"的消息。

好吧!消息会丢失,因为它不匹配任何捆绑规则。

On the other hand "lazy.orange.male.rabbit", even though it has four words, will match the last binding and will be delivered to the second queue.

但是 "lazy.orange.male.rabbit"这种routing key,尽管它有四个单词,但是还是会进入到第二个队列(为喵呢?你来说说)

Topic exchange

Topic exchange is powerful and can behave like other exchanges.

Topic 交换器很强大,它可以模拟其他交换器的行为

When a queue is bound with "#" (hash) binding key - it will receive all the messages, regardless of the routing key - like in fanout exchange.

当一个队列捆绑一个#的binding key——它会像fanout交换器一样,忽略掉routing key,接收所有的消息.(还记得#代表什喵么?)

When special characters "*" (star) and "#" (hash) aren't used in bindings, the topic exchange will behave just like a direct one.

在捆绑中如果没有使用特殊字符星号和井号,topic交换器的行为就跟定向交换器一样。

Putting it all together(合体!!!烦死了是吧?哈,还有一次!)

We're going to use a topic exchange in our logging system. We'll start off with a working assumption that the routing keys of logs will have two words: ".".

在我们的日志系统中使用topic交换器。我们假设日志的routing keyes有"."组成。

The code is almost the same as in the previous tutorial.

代码和之前的几乎一妈生的。

The code for emit_log_topic.php:

emit_log_topic.php代码:

<?php require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use PhpAmqpLib\Connection\AMQPConnection;
use PhpAmqpLib\Message\AMQPMessage;

$connection = new AMQPConnection(&#39;localhost&#39;, 5672, &#39;guest&#39;, &#39;guest&#39;);
$channel = $connection->channel();

$channel->exchange_declare('topic_logs', 'topic', false, false, false);

$routing_key = $argv[1];
if(empty($routing_key)) $routing_key = "anonymous.info";
$data = implode(' ', array_slice($argv, 2));
if(empty($data)) $data = "Hello World!";

$msg = new AMQPMessage($data);

$channel->basic_publish($msg, 'topic_logs', $routing_key);

echo " [x] Sent ",$routing_key,':',$data," \n";

$channel->close();
$connection->close();

?>

The code for receive_logs_topic.php:

<?php require_once __DIR__ . &#39;/vendor/autoload.php&#39;;
use PhpAmqpLib\Connection\AMQPConnection;

$connection = new AMQPConnection(&#39;localhost&#39;, 5672, &#39;guest&#39;, &#39;guest&#39;);
$channel = $connection->channel();

$channel->exchange_declare('topic_logs', 'topic', false, false, false);

list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);

$binding_keys = array_slice($argv, 1);
if( empty($binding_keys )) {
    file_put_contents('php://stderr', "Usage: $argv[0] [binding_key]\n");
    exit(1);
}

foreach($binding_keys as $binding_key) {
    $channel->queue_bind($queue_name, 'topic_logs', $binding_key);
}

echo ' [*] Waiting for logs. To exit press CTRL+C', "\n";

$callback = function($msg){
  echo ' [x] ',$msg->delivery_info['routing_key'], ':', $msg->body, "\n";
};

$channel->basic_consume($queue_name, '', false, true, false, false, $callback);

while(count($channel->callbacks)) {
    $channel->wait();
}

$channel->close();
$connection->close();

?>

To receive all the logs:

接收所有日志:

$ php receive_logs_topic.php "#"

To receive all logs from the facility "kern":

接收所有来自kern的日志:

$ phpreceive_logs_topic.php "kern.*"

Or if you want to hear only about "critical" logs:

或是你想仅仅接收”致命“日志

$ php receive_logs_topic.php "*.critical"

You can create multiple bindings:

你也可以多重绑定

$ php receive_logs_topic.php "kern.*" "*.critical"

And to emit a log with a routing key "kern.critical" type:

发布一个带有"kern.critical"routing key的日志就输入:

$ php emit_log_topic.php "kern.critical" "A critical kernel error"

Have fun playing with these programs. Note that the code doesn't make any assumption about the routing or binding keys, you may want to play with more than two routing key parameters.
 

玩的开心哈!注意上面的代码没有做路由或捆绑的例子,有可能想体验两个以上的routing key参数。

Some teasers:

  • Will "*" binding catch a message sent with an empty routing key?
  • 星号会匹配带有空routing key的消息吗?
  • Will "#.*" catch a message with a string ".." as a key? Will it catch a message with a single word key?
  • "#.*"会匹配".."的消息吗? 它是匹配到一个单一的单词吗?
  • How different is "a.*.#" from "a.#"?
  • "a.*.#"和"a.#"有啥不同?

(Full source code for emit_log_topic.php and receive_logs_topic.php)

emit_log_topic.php和receive_logs_topic.php源码。

Next, find out how to do a round trip message as a remote procedure call in tutorial 6

下次,我们讲如何像远程过程调用一样完成信息往返。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何在PHP中使用RabbitMQ实现分布式消息处理如何在PHP中使用RabbitMQ实现分布式消息处理Jul 18, 2023 am 11:00 AM

如何在PHP中使用RabbitMQ实现分布式消息处理引言:在大规模应用程序开发中,分布式系统已成为一个常见的需求。分布式消息处理是这样的一种模式,通过将任务分发到多个处理节点,可以提高系统的效率和可靠性。RabbitMQ是一个开源的,可靠的消息队列系统,它采用AMQP协议来实现消息的传递和处理。在本文中,我们将介绍如何在PHP中使用RabbitMQ来实现分布

在Go语言中使用RabbitMQ:完整指南在Go语言中使用RabbitMQ:完整指南Jun 19, 2023 am 08:10 AM

随着现代应用程序的复杂性增加,消息传递已成为一种强大的工具。在这个领域,RabbitMQ已成为一个非常受欢迎的消息代理,可以用于在不同的应用程序之间传递消息。在这篇文章中,我们将探讨如何在Go语言中使用RabbitMQ。本指南将涵盖以下内容:RabbitMQ简介RabbitMQ安装RabbitMQ基础概念Go语言中的RabbitMQ入门RabbitMQ和Go

SpringBoot怎么整合RabbitMQ实现延迟队列SpringBoot怎么整合RabbitMQ实现延迟队列May 16, 2023 pm 08:31 PM

如何保证消息不丢失rabbitmq消息投递路径生产者->交换机->队列->消费者总的来说分为三个阶段。1.生产者保证消息投递可靠性。2.mq内部消息不丢失。3.消费者消费成功。什么是消息投递可靠性简单点说就是消息百分百发送到消息队列中。我们可以开启confirmCallback生产者投递消息后,mq会给生产者一个ack.根据ack,生产者就可以确认这条消息是否发送到mq.开启confirmCallback修改配置文件#NONE:禁用发布确认模式,是默认值,CORRELATED:

go-zero与RabbitMQ的应用实践go-zero与RabbitMQ的应用实践Jun 23, 2023 pm 12:54 PM

现在越来越多的企业开始采用微服务架构模式,而在这个架构中,消息队列成为一种重要的通信方式,其中RabbitMQ被广泛应用。而在go语言中,go-zero是近年来崛起的一种框架,它提供了很多实用的工具和方法,让开发者更加轻松地使用消息队列,下面我们将结合实际应用,来介绍go-zero和RabbitMQ的使用方法和应用实践。1.RabbitMQ概述Rabbit

Swoole与RabbitMQ集成实践:打造高可用性消息队列系统Swoole与RabbitMQ集成实践:打造高可用性消息队列系统Jun 14, 2023 pm 12:56 PM

随着互联网时代的到来,消息队列系统变得越来越重要。它可以使不同的应用之间实现异步操作、降低耦合度、提高可扩展性,进而提升整个系统的性能和用户体验。在消息队列系统中,RabbitMQ是一个强大的开源消息队列软件,它支持多种消息协议、被广泛应用于金融交易、电子商务、在线游戏等领域。在实际应用中,往往需要将RabbitMQ和其他系统进行集成。本文将介绍如何使用sw

Golang中使用RabbitMQ实现任务分发与负载均衡的策略Golang中使用RabbitMQ实现任务分发与负载均衡的策略Sep 27, 2023 am 11:22 AM

Golang中使用RabbitMQ实现任务分发与负载均衡的策略概述:在分布式系统中,任务的分发与负载均衡是非常重要的。一种常见的解决方案是使用消息队列来实现任务的分发与处理。本文将介绍如何使用Golang和RabbitMQ实现任务的分发与负载均衡的策略,并提供具体的代码示例。RabbitMQ简介:RabbitMQ是一个可靠、可扩展、开放源代码的消息中间件,它

SpringBoot怎么整合RabbitMQ处理死信队列和延迟队列SpringBoot怎么整合RabbitMQ处理死信队列和延迟队列May 15, 2023 pm 03:28 PM

简介RabbitMQ消息简介RabbitMQ的消息默认不会超时。什么是死信队列?什么是延迟队列?死信队列:DLX,全称为Dead-Letter-Exchange,可以称之为死信交换器,也有人称之为死信邮箱。当消息在一个队列中变成死信(deadmessage)之后,它能被重新被发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列。以下几种情况会导致消息变成死信:消息被拒绝(Basic.Reject/Basic.Nack),并且设置requeue参数为false;消息过期;队

PHP开发:使用 RabbitMQ 实现任务队列PHP开发:使用 RabbitMQ 实现任务队列Jun 15, 2023 pm 05:33 PM

随着互联网的不断发展,网站的流量越来越大,访问量的增长带来的问题也越来越多。当用户量过大时,服务器负载会增大,这时就需要使用一些技术手段来解决这些问题。任务队列就是其中的一种方式,可以将一些耗时的操作异步执行,从而缓解服务器压力。本文将介绍如何使用RabbitMQ实现任务队列。一、什么是RabbitMQRabbitMQ是一个开源的消息中间件,它实现了

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),