RabbitMQ學習(5) 主題

2022-01-14 07:53:09 字數 3760 閱讀 4502

我們改進了我們的日誌系統 

我們沒有使用只有虛擬廣播

fanout

交換機,而是使用direct

交換機,並有選擇性地接收日誌的可能性。

儘管使用

直接交換改進了我們的系統,但它仍然有侷限性 - 它不能根據多個標準進行路由選擇。

在我們的日誌系統中,我們可能不僅要根據嚴重性來訂閱日誌,還要根據發出日誌的**進行訂閱。

你可能從

syslog

unix工具

知道這個概念 

,它根據嚴重性(info / warn / crit ...)和facility(auth / cron / kern ...)來路由日誌。

這會給我們很大的靈活性 - 我們可能想要聽取來自'cron'的嚴重錯誤,而且還要聽取來自'kern'的所有日誌。

為了在我們的日誌系統中實現這一點,我們需要了解更複雜的

話題交換。

傳送到主題交換的

訊息不能有任意的 

routing_key- 它必須是由點分隔的單詞列表。

這些單詞可以是任何東西,但通常它們指定連線到訊息的一些功能。

一些有效的路由鍵例子:「 

stock.usd.nyse」,「 

nyse.vmw」,「 

quick.orange.rabbit」。

在路由選擇鍵中可以有任意數量的字,最多255個位元組。

繫結鍵也必須是相同的形式。

主題交換

背後的邏輯 

類似於直接的- 使用特定的路由金鑰傳送的訊息將被傳送到與匹配的繫結金鑰繫結的所有佇列。

但是繫結鍵有兩個重要的特殊情況:

在乙個例子中解釋這個很簡單:

在這個例子中,我們將傳送所有描述動物的資訊。

訊息將使用由三個字(兩個點)組成的路由鍵傳送。

路由關鍵字中的第乙個單詞將描述速度,第二個顏色和第三個種類:「 

。。」。

我們建立了三個繫結:q1繫結了繫結鍵「 

* .orange。*」,q2 

繫結了「 

*。*。rabbit」和「 

lazy。#」。

這些繫結可以概括為:

將路由鍵設定為「 

quick.orange.rabbit」的訊息將傳遞到兩個佇列。

訊息「 

lazy.orange.elephant」也將去他們兩個。

另一方面,「 

quick.orange.fox」只會到第乙個佇列,而「 

lazy.brown.fox」只會到第二個佇列。

即使匹配兩個繫結,

「 lazy.pink.rabbit」也只會被傳遞到第二個佇列一次。

「 quick.brown.fox」不匹配任何繫結,因此將被丟棄。

如果我們違反我們的合同,並傳送乙個或四個單詞,如「 

橙色」或「 

quick.orange.male.rabbit」 

的訊息會發生什麼

?那麼,這些訊息將不匹配任何繫結,將會丟失。

另一方面,「 

lazy.orange.male.rabbit」即使有四個單詞,也會匹配最後乙個繫結,並被傳遞到第二個佇列。

話題交換

話題交換功能強大,可以像其他交流一樣行事。

當乙個佇列繫結了「 

#」(雜湊)繫結金鑰時,它將接收所有的訊息,而不管路由金鑰如何在

扇出交換。

當在繫結中不使用

特殊字元「 

*」(星號)和「 

#」(雜湊)時,主題交換將像

直接交換一樣

。我們將

在我們的日誌系統中

使用話題交換。

我們首先假定日誌的路由鍵有兩個字:「 

。」emitlogtopic.cs的**

public

static

void main(string

args)

;using(var connection =factory.createconnection())

using(var channel =connection.createmodel())

':''

", routingkey, message);}}

receivelogstopic.cs的**

public

static

void main(string

args)

;using(var connection =factory.createconnection())

using(var channel =connection.createmodel())

[binding_key...]",

environment.getcommandlineargs()[

0]);

console.writeline(

"press [enter] to exit.");

console.readline();

environment.exitcode = 1

;

return

; }

foreach(var bindingkey in

args)

console.writeline(

"[*] waiting for messages. to exit press ctrl+c");

var consumer = new

eventingbasicconsumer(channel);

consumer.received += (model, ea) =>':''",

routingkey,

message);

};channel.basicconsume(queue: queuename,

autoack:

true

, consumer: consumer);

console.writeline(

"press [enter] to exit.");

console.readline();}}

要接收所有日誌:

cd receivelogstopic

dotnet run "#"

要接收來自設施「 

kern」的

所有日誌

cd receivelogstopic

dotnet run "kern.*"

或者如果你只想聽到關於「 

關鍵」日誌:

receivelogstopic.exe "*.critical"
您可以建立多個繫結:

cd receivelogstopic

dotnet run "kern.*" "*.critical"

並傳送乙個路由鍵「 

kern.critical」型別

的日誌:

cd emitlogtopic

dotnet run "kern.critical" "a critical kernel error"

玩這些程式玩得開心。

請注意,**不會對路由或繫結鍵作任何假設,您可能需要使用兩個以上的路由鍵引數。

rabbitmq學習5 主題交換機

require once dir vendor autoload.php use phpamqplib connection amqpstreamconnection use phpamqplib message amqpmessage connection new amqpstreamconnec...

rabbitmq路由模式 訂閱 主題

1.依賴 junit junit 4.12 test com.rabbitmq amqp client 3.5.1 2.訊息提供者 public class test 4 direct provider 3.訊息接收者 public class test 4 direct consumer1 6,連...

rabbitmq 理論 主題交換機

儘管直連交換機能夠改善我們的系統,但是它也有它的限制 沒辦法基於多個標準執行路由操作。在我們的日誌系統中,我們不只希望訂閱基於嚴重程度的日誌,同時還希望訂閱基於傳送 的日誌。unix工具syslog就是同時基於嚴重程度 severity info warn crit.和 裝置 facility au...