Ceilometer 17、rabbitmq原理介紹
1 rabbitmq訊息處理過程
生產者將資訊傳送到交換機,交換機根據繫結鍵將資訊傳送到佇列,消費者從佇列中獲取資料。
交換機知道資訊到達時應該如何處理它。
如何處理就是根據交換機的型別確定的。
2 交換機以及繫結
交換機型別: direct, topic, headers, fanout
關於交換機和佇列,存在繫結關係,具體語法如下:
channel.queue_bind(exchange=exchange_name,
queue=queue_name)
表示佇列對來自於某個交換機上的資訊感興趣
channel.queue_bind(exchange=exchange_name,
queue=queue_name,
routing_key='black')
繫結可以新增額外的引數: routing_extra,,為了避免與basic_publish
引數的混淆,我們稱它為繫結鍵binding key。
這意味著繫結鍵依賴於交換機型別,對於fanout,忽略繫結鍵。
2.1 fanout交換機
如果交換機型別為: fanout:廣播資訊到所有佇列上
訊息佇列模型如下:
Producer ---> Exchange(type=fanout) ---> amq.gen-RQ6... ---> Consumer1
---> amq.gen-RQ6... ---> Consumer2
2.2 direct交換機
交換機型別如果為: direct.那麼繫結鍵會正確匹配訊息的路由鍵。
訊息佇列模型如下:
---> RoutingKey(error) ---> amqp.gen-S9b... ---> Consumer1
Producer ---> Exchange(type=direct) ---> RoutingKey(info) ---> amqp.gen-Ag1... ---> Consumer2
---> RoutingKey(error) ---> amqp.gen-Ag1... ---> Consumer2
---> RoutingKey(warning) ---> amqp.gen-Ag1... ---> Consumer2
多個佇列可以通過相同的繫結鍵繫結。
實際上就是交換機型別為direct,繫結鍵是同樣的,但是繫結到多個佇列上。
2.3 topic交換機
交換機型別如果為: topic, 它就沒有routing_key。它必須是一個字串列表,
以點號分隔。例如:
"quick.orange.rabbit"
繫結鍵也必須是以相同格式,。
* 可以代替任何一個字元
# 可以替代0或多個字元
訊息佇列模型如下:
-----> RoutingKey (*.orange.*)--->Queue1---> Consumer1
Producer---> Exchange(type=topic) -----> RoutingKey (*.*.rabbit)--->Queue2---> Consumer2
-----> RoutingKey (lazy.#) --->Queue2---> Consumer2
如果topic交換機的繫結鍵用 # ,它的行為就變成了fanout的交換機類似;
如果topic交換機的繫結鍵用 不用#和*, 它的行為就變成了和direct的交換機類似。
3 基於rabbitmq訊息佇列的rpc遠端程序通訊
客戶端需要呼叫服務端的方法,
模型如下:
Client-----> Request,reply_to=CallBackQueue,correlation_id=abc --------------> rpc_queue ------------->Server
<----- Reply, correlation_id=abc <-----------reply_to=CallBackQueue<-----
處理過程:
1) 客戶端啟動,建立一個匿名的回撥佇列
2) 對於一個RPC請求,客戶端傳送的資訊帶有兩個屬性:
reply_to: 表示回撥的佇列, correlation_id: 對每個請求的唯一值
3) 請求被髮送到rpc佇列
4) RPC服務端監聽佇列上的請求,當請求出現,它完成任務,併發送一個攜帶有結果的訊息到客戶端,
將訊息傳送到回撥佇列
5) 客戶端等待回撥佇列上的資料,當訊息出現,它檢測correlation_id是否正確。
4 rabbitmq常用命令
4.1 列出所有交換機
sudo rabbitmqctl list_exchanges
返回結果樣例如下:
ceilometer topic
ceilometer.agent.compute_fanout fanout
q-metering-plugin_fanout fanout
解釋:
上述第一列表示: 交換機名稱, 上述第二列表示: 交換機型別
4.2 列出所有繫結
sudo rabbitmqctl list_bindings
返回結果樣例如下:
exchange alarm_notifier queue alarm_notifier []
exchange alarm_notifier.node-1.domain.tld queue alarm_notifier.node-1.domain.tld []
exchange alarm_notifier_fanout_b129173ee8d9440286a42faf19355a94 queue alarm_notifier_fanout_b129173ee8d9440286a42faf19355a94 []
exchange ceilometer.agent.compute queue ceilometer.agent.compute []
exchange ceilometer.agent.compute.node-1.domain.tld queue ceilometer.agent.compute.node-1.domain.tld []
exchange ceilometer.agent.compute.node-2.domain.tld queue ceilometer.agent.compute.node-2.domain.tld []
exchange ceilometer.agent.compute.node-3.domain.tld queue ceilometer.agent.compute.node-3.domain.tld []
exchange ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 queue ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 []
exchange ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b queue ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b []
exchange metering.sample queue metering.sample []
exchange notifications.error queue notifications.error []
exchange notifications.info queue notifications.info []
exchange notifications.sample queue notifications.sample []
解釋:
上述各個列含義如下
exchange exchange_name queue queue_name
分析:
nova exchange notifications.error queue notifications.error []
nova exchange notifications.info queue notifications.info []
nova exchange notifications.sample queue notifications.sample []
可以看到經過oslo.messaging封裝後,
真實exchange名稱=exchange名稱 + oslo.messaging物件呼叫的方法名稱(例如: info, error, sample)
佇列名稱=真實exchange名稱
所以說: oslo.messaging對rabbitmq還是封裝了很多東西
4.3 列出所有佇列
rabbitmqctl list_queues
返回結果示例:
ceilometer.agent.compute 0
ceilometer.agent.compute.node-1.domain.tld 0
ceilometer.agent.compute.node-2.domain.tld 0
ceilometer.agent.compute.node-3.domain.tld 0
ceilometer.agent.compute_fanout_5cd3fcae2e7e47f7a76c14833a9a97f2 0
ceilometer.agent.compute_fanout_b5d6a8b206944688b0b62b3a6f7f7e4b 0
解釋:
上述各個列含義如下
佇列名稱 訊息個數
注意:消費者建立佇列,不是生產者
參考:
[1] http://www.rabbitmq.com/tutorials/tutorial-one-python.html
[2] http://www.rabbitmq.com/tutorials/tutorial-two-python.html
[3] http://www.rabbitmq.com/tutorials/tutorial-three-python.html
[4] http://www.rabbitmq.com/tutorials/tutorial-four-python.html
[5] http://www.rabbitmq.com/tutorials/tutorial-five-python.html
[6] http://www.rabbitmq.com/tutorials/tutorial-six-python.html