RabbitMQ(三) ——發布訂閱
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(三) ——發布訂閱