天天看點

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

在 rabbitmq-c代碼中可以看到如下代碼

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

上圖所示為queue聲明時使用的結構體。其中最容易讓使用者迷惑的3個屬性是durable、exclusive和auto_delete。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

上圖所示為consumer從queue進行消息消費時用于設定屬性的結構體。其中最容易讓使用者迷惑的屬性是exclusive(上圖中的exclusive注釋有點問題,請忽略)。

在編寫python語言的測試程式時,我将行為分為以下幾步

聲明7個具有不同屬性的queue,分别和名為test_exchage的exchange進行綁定(因為exchange為fanout類型,是以測試代碼中的routing_key其實是不起作用的);

向exchange發送具有persistent屬性的消息(delivery_mode=2);

建立7個消費者分别從上述7個queue中擷取消息;

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

測試結果如下

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

可以看到,所有的7個消費者均收到了對應的消息内容。 

下面我們從rabbitmq伺服器測檢視以下上述測試能展現什麼資訊。

1.client和server建立了一條amqp connection。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

2.在該connection上使用了channel号1程序amqp協定通信。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

3.連接配接建立時的使用者名為guest,以及各種channel屬性設定情況。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

4.在目前channel上共存在7個消費者,分别從7個不同的queue上擷取消息;該channel上的消息均來自名為test_exchage的exchange(請原諒我測試過程中的英文拼寫錯誤)。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

從exchanges頁籤上可以看到test_exchage下綁定了哪些queue。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

從queues頁籤上可以看到全部7個queue的屬性情況

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

看到這裡,眼尖的同學可能會發現問題所在了,那就是用戶端代碼中聲明的queue屬性并沒有全部生效,為什麼會這樣呢?

首先分别看一下代碼中聲明的7個queue在伺服器側的詳細資訊。

a.test_1_queue沒有設定任何屬性,在界面上沒有看到任何屬性。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

b. test_2_queue設定了durable屬性,在界面上看到了“durable:true”。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

c. test_3_queue設定了auto-delete屬性,在界面上看到了“auto-delete:true”。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

d. test_4_queue同時設定了durable和auto-delete屬性,在界面上看到了“durable:true和auto-delete:true”。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

e. test_5_queue同時設定了durable和exclusive屬性,但在界面上隻看到了“exlusive owner”的存在。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

f. test_6_queue同時設定了auto_delete和exclusive屬性,在界面上同時看到“auto-delete:true”和“exlusive owner”的存在。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

g. test_7_queue同時設定了durable、auto_delete和exclusive屬性,在界面上隻看到了“auto-delete:true”和“exlusive owner”的存在。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本
【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

綜上,可以得出如下結論

durable屬性和auto-delete屬性可以同時生效;

durable屬性和exclusive屬性會有性質上的沖突,兩者同時設定時,僅exclusive屬性生效;

auto_delete屬性和exclusive屬性可以同時生效;

除此之外,還能得到其它一些有趣的結論:

queue的“exlusive owner”對應的是connection而不是channel;

consumer存在于某個channel上的;

 附上一張用戶端同時設定durable、auto_delete和exclusive屬性的抓包截圖:

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

下面通過改變client側代碼,模拟不同情況下各種屬性對queue的存在情況的影響。

a.在成功建立全部7個queue後,通過ctrl+c異常終止用戶端程式。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

(上圖為全部建立時的狀态)

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

 停止後,queue的情況如下圖所示。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

對比發現,此時隻有 test_1_queue 和 test_2_queue 仍舊存在,其它queue已經被rabbitmq伺服器删除掉了(思考原因)。

b.用戶端側執行到消息發送後,結束目前操作(無consumer情況)。代碼調整如下

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

此時仍舊可以看到queue的聲明和綁定都是成功的。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

此時用戶端程式執行後會自動退出

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

再從web頁面檢視queue的情況如下

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

對比發現,此時僅test_1_queue、test_2_queue、test_3_queue和test_4_queue 存在(思考原因)。

      這裡有個細節值得說一下:雖然最終我們在web頁面上隻看到了4個queue的存在,但其實7個queue都被成功建立過(抓包可以證明),如果你夠幸運,你也可能在web頁面上看到一閃而過的另外3個queue。通過對比可以發現,導緻另外3個queue消失的原因是exclusive屬性的設定,前面我已經說過,queue的“exlusive owner”對應的是connection,是以在這個實驗中可以确定的是,connection仍舊是存在的(這裡遺留個問題:為什麼python執行退出後連接配接仍舊存在),而此時實際上不存在的是consumer,是以需要對之前得到的結論進行加強:具有exclusive屬性的queue的存在條件是在connection上存在某個consumer訂閱了該queue。同樣可以得到另外一個結論:可以在沒有建立consumer的情況下,建立出具有auto-delete屬性的queue。

在rabbitmq官方文檔中其實已經對上述現象進行了說明,隻不過一語帶過,不注意的話容易忽略掉。在queue.declare方法中包含如下屬性說明

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

此時肯定有人會問,除了queue.declare中具有exclusive屬性,basic.consume中也具有exclusive屬性,後者是什麼含義呢?在文檔說明中有如下内容

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

由此可以了解兩個屬性的差異和實際使用中應該注意的問題是什麼!(自行思考)

在此情況下,若執行rabbitmq server的重新開機(rabbitmqctl stop_app;rabbitmqctl start_app),可以看到僅有test_2_queue和test_4_queue仍舊存在。

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

以上測試基于如下rabbitmq版本

【原創】RabbitMQ之Queue屬性測試 常用queue屬性 測試過程測試版本

為什麼使用這個版本?(我猜肯定有人會問)因為這個實驗是我半年前就已經完成了的~~