1. 程式人生 > >RabbitMQ(三) ——發布訂閱

RabbitMQ(三) ——發布訂閱

運行時 接受 exchange 當前 發送消息 關註 gpo center array

RabbitMQ(三)

——發布訂閱

(轉載請附上本文鏈接——linhxx)

一、概述

RabbitMQ的發布訂閱(Publish/Subscribe),其將生產者和消費者進一步解耦,生產者生產消息後,交付給交換機,消費者上線後,主動主動去隊列中取數據進行處理。該模式也符合上一節工作隊列中的ack、預取等規則。

發布訂閱模式如下圖所示:

技術分享圖片

二、交換機(exchange)

生產者生產完消息之後,都是將消息通過channel交給交換機,即生產者並不直接和隊列聯系。在沒有定義交換機的時候,RabbitMQ會啟用內部預定義的交換機。即所有沒有定義交換機,直接采用生產者發送消息到隊列的,都是將消息發送給默認交換機。

交換機是一個很簡單的東西,即將生產者發送的消息,按照預先定好的規則,轉發給對應的隊列。

1、廣播發送

rabbitmq中,交換機的規則有fanout、direct、topic、headers等。本節的發布訂閱模式,主要可以采用fanout模式。

fanout,類似網絡技術中,子網的廣播發送模式。即,fanout模式下,交換機會將信息發送給所有與其綁定的隊列,即實現“發布”的功能。通常,再將每個隊列給不同的消費者去消費,實現每個消費者都可以取到該消息,並各自進行後續相應的處理。

fanout模式如下圖所示:

技術分享圖片

  

2、註意事項

1)提前綁定

fanout模式下,需要提前將交換機與隊列進行綁定,一個交換機可以綁定多個隊列,一個隊列可以同多個交換機進行綁定。接受到消息的交換機沒有與任何隊列綁定,則消息會被拋棄。

2)該模式不需要routing key。

3、使用

1)使用

$channel->exchange_declare(‘logs‘, ‘fanout‘, false, false, false);

$channel->basic_publish($msg, ‘logs‘);

其中,第一個參數是交換機的名字,第二個參數,是交換機的模式。如果沒有定義交換機的名稱、模式,則采用默認的交換機轉發生產者的消息。即可以看作,空字符串’’也是交換機的一個名字。

2)查看當前交換機數量

cli模式下,sudo rabbitmqctl list_exchanges

三、臨時隊列(Temporary queues)

當rabbitmq運行時,隊列的名字非常重要,因為其在生產者方,交換機會將信息按照名字發送給隊列,而消費者方,消費者需要通過隊列的名字去隊列取消息。因此,隊列是rabbitmq中連接生產者與消費者的橋梁。

當開始使用時,需要的是一個空的、未被使用的隊列;當連接斷開,需要將隊列關閉。

1、隊列取名

為了保證隊列是一個全新的隊列,需要將給隊列取一個隨機的名字。rabbitmq提供了系統隨機給生成隊列名的方式,如下:

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

即,當queue_declare時沒有指定名字,采用空字符串"",則rabbitmq會給隊列取一個隨機的名字,形如amq.gen-JzTY20BRgKO-HjmUJj0wLg,則可以使用$queue_name,其就是隊列的名字。

2、php的list

上述list是php中的list的用法,上述式子表示$channel->queue_declare("");的結果是一個含有3個元素的數組,將第一個元素賦值給$queue_name。

list()不是一個函數,而是類似array()一樣的用法。

PHP官方文檔中,list的示例:

$info = array(‘coffee‘, ‘brown‘, ‘caffeine‘);

list( , , $power) = $info;//$power=’caffeine’

四、綁定(binding)

上述提到,交換機必須與隊列綁定,如果沒有隊列和交換機綁定,交換機會丟棄接收到的消息。綁定方式如下:

$channel->queue_bind($queue_name, ‘logs‘);

其中,第一個參數是隊列的名字,第二個參數是交換機的名字。

在cli中,查看綁定的方式如下:rabbitmqctl list_bindings。

——written by linhxx

更多最新文章,歡迎關註微信公眾號“決勝機器學習”,或掃描右邊二維碼。技術分享圖片

RabbitMQ(三) ——發布訂閱