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

译-PHP rabbitMQ Tutorial-5

Jun 06, 2016 pm 07:43 PM
rabbitmq

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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1663
14
CakePHP 教程
1420
52
Laravel 教程
1313
25
PHP教程
1266
29
C# 教程
1238
24
如何利用React和RabbitMQ建立可靠的訊息應用 如何利用React和RabbitMQ建立可靠的訊息應用 Sep 28, 2023 pm 08:24 PM

如何利用React和RabbitMQ建立可靠的訊息傳遞應用程式引言:現代化的應用程式需要支援可靠的訊息傳遞,以實現即時更新和資料同步等功能。 React是一種流行的JavaScript庫,用於建立使用者介面,而RabbitMQ是一種可靠的訊息傳遞中間件。本文將介紹如何結合React和RabbitMQ建立可靠的訊息傳遞應用,並提供具體的程式碼範例。 RabbitMQ概述:

如何在PHP中使用RabbitMQ實現分散式訊息處理 如何在PHP中使用RabbitMQ實現分散式訊息處理 Jul 18, 2023 am 11:00 AM

如何在PHP中使用RabbitMQ實現分散式訊息處理引言:在大規模應用程式開發中,分散式系統已成為一個常見的需求。分散式訊息處理是這樣的一種模式,透過將任務分發到多個處理節點,可以提高系統的效率和可靠性。 RabbitMQ是一個開源的,可靠的訊息佇列系統,它採用AMQP協定來實現訊息的傳遞和處理。在本文中,我們將介紹如何在PHP中使用RabbitMQ來實現分佈

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語言中使用RabbitMQ:完整指南 在Go語言中使用RabbitMQ:完整指南 Jun 19, 2023 am 08:10 AM

隨著現代應用程式的複雜性增加,訊息傳遞已成為一種強大的工具。在這個領域,RabbitMQ已成為一個非常受歡迎的訊息代理,可以用於在不同的應用程式之間傳遞訊息。在這篇文章中,我們將探討如何在Go語言中使用RabbitMQ。本指南將涵蓋以下內容:RabbitMQ簡介RabbitMQ安裝RabbitMQ基礎概念Go語言中的RabbitMQ入門RabbitMQ和Go

go-zero與RabbitMQ的應用實踐 go-zero與RabbitMQ的應用實踐 Jun 23, 2023 pm 12:54 PM

現在越來越多的企業開始採用微服務架構模式,而在這個架構中,訊息佇列成為一種重要的通訊方式,其中RabbitMQ被廣泛應用。而在go語言中,go-zero是近年來崛起的一種框架,它提供了許多實用的工具和方法,讓開發者更輕鬆地使用訊息佇列,下面我們將結合實際應用,來介紹go-zero和RabbitMQ的使用方法和應用實務。 1.RabbitMQ概述Rabbit

Golang與RabbitMQ實現即時資料同步的解決方案 Golang與RabbitMQ實現即時資料同步的解決方案 Sep 27, 2023 pm 10:41 PM

Golang與RabbitMQ實現即時數據同步的解決方案引言:當今時代,隨著互聯網的普及和數據量的爆發式增長,即時數據的同步變得越來越重要。為了解決資料非同步傳輸和資料同步的問題,許多公司開始採用訊息佇列的方式來實現資料的即時同步。本文將介紹基於Golang和RabbitMQ的即時資料同步的解決方案,並提供具體的程式碼範例。一、什麼是RabbitMQ? Rabbi

Swoole與RabbitMQ整合實務:打造高可用性訊息佇列系統 Swoole與RabbitMQ整合實務:打造高可用性訊息佇列系統 Jun 14, 2023 pm 12:56 PM

隨著網路時代的到來,訊息佇列系統變得越來越重要。它可以使不同的應用之間實現非同步操作、降低耦合度、提高可擴展性,進而提升整個系統的效能和使用者體驗。在訊息佇列系統中,RabbitMQ是一個強大的開源訊息佇列軟體,它支援多種訊息協定、被廣泛應用於金融交易、電子商務、線上遊戲等領域。在實際應用中,往往需要將RabbitMQ和其他系統整合。本文將介紹如何使用sw

Golang RabbitMQ: 實現高可用的訊息佇列系統的架構設計與實現 Golang RabbitMQ: 實現高可用的訊息佇列系統的架構設計與實現 Sep 28, 2023 am 08:18 AM

GolangRabbitMQ:實現高可用的訊息佇列系統的架構設計和實現,需要具體程式碼範例引言:隨著網路技術的不斷發展和應用的廣泛,訊息佇列成為了現代軟體系統中不可或缺的一部分。作為實現解耦、非同步通訊、容錯處理等功能的工具,訊息佇列為分散式系統提供了高可用性和擴充性的支援。而Golang作為一種高效、簡潔的程式語言,廣泛應用於建構高並發和高效能的系統

See all articles