1. 程式人生 > 其它 >RabbitMQ(三) ——釋出訂閱

RabbitMQ(三) ——釋出訂閱

RabbitMQ(三)——釋出訂閱

(原創內容,轉載請註明來源,謝謝)

一、概述

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 2017.08.21