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