RabbitMQ學習(十): AMQP 0-9-1協議之Consumer and Message

說明

通過上篇博文翻譯了AMQP協議中有關隊列Queues的相關內容,本篇博文將繼續翻譯官方關於AMQP協議介紹的有關Consumer和Message部分的內容。通過翻譯,學習記錄在RabbitMQ中AMQP協議的Consumer和Message的作用。

正文

Consumers

隊列中存儲的消息如果不能被程序消費處理,那它們就是無用的。在AMQP 0-9-1模型中,應用程序有兩種方式從隊列獲取消息:

  • 消息被推送到應用程序中(push 模式)
  • 程序按需從隊列中拉取消息(pull 模式)

當使用push模式時,應用程序必須表明它對某個特定的隊列中的消息感興趣。當以這種方式消費消息時,我們稱之爲在隊列註冊了一個消費者,或者簡單來說,隊列有了一個訂閱者。每個隊列都存在不止一個消費者的情況,或者是註冊了一個具有獨佔性的消費者(當消費時,禁止其它消費者在此隊列消費消息,具有獨佔性)。

每個消費者(訂閱者)都有一個被稱爲消費者標籤(consumer tag)的憑證,它被用來取消對消息的訂閱。這些標籤只能是字符串類型的。


Message Acknowledgements

消費者程序是指接收和處理消息的應用程序。程序在處理消息時可能會失敗或者程序可能會崩潰,還有網絡也可能發生問題,這裏就引起一個問題:AMQP代理服務器什麼時候可以將消息從隊列中刪除?AMQP 0-9-1協議提出了兩種方案:

  • 在服務器將消息發送給應用程序後(使用AMQP的basic.deliver或basic.get-ok方法)
  • 在應用程序發送一個確認消息後(使用AMQP的basic.ack方法)

第一種方案稱爲自動確認模式,第二種稱爲顯示確認模式。當使用顯示確認模式時,應用程序可以選擇在什麼時候發送確認消息。可以在接收到消息後,或者在存儲消息後處理消息前,又或者在完全將消息處理結束後(例如,成功獲取一個網頁,在處理並存儲後發送確認)。

如果一個消費者在未發送確認消息時宕機,AMQP代理服務器將重新把消息發送給其他消費者,或者在沒有其他消費者的情況下,服務器將一直保存消息直到有消費者註冊到該隊列,進行重新派發。


Rejecting Messages

當消費者接收處理一個消息時,可能會失敗。這時應用程序應該通過一個拒絕消息向服務器表明該消息處理失敗(或當時無法完成)。當拒絕一個消息時,應用程序可以要去服務器丟棄或重新入隊派發該消息。當隊列只有一個消費者是,要確保在拒絕消息時不會造成消息被不斷重複派發的無限循環,出現一個消息在同一個消費者上不斷地被入隊重新派發。


Negative Acknowledgements

使用AMQP的basic.reject方法來拒絕消息,但是該方法有一個限制:無法像確認那樣一次拒絕多個消息,但是RabbitMQ有一個解決方案,RabbitMQ提供了一個AMQP協議的擴展,被稱爲消極確認(negative acknowledgements)或acks。更多的詳細信息,請參照the help page


Prefetching Messages

在多個消費者共享一個隊列時,能夠指定每個消費者可以在下次消息確認前,被一次推送多少個消息是有用的。這個方法可以作爲簡單的負載均衡奇數或者在消息傾向被批量發送時可以提供系統的吞吐量。比如,如果生產者由於工作性質每分鐘都發送消息時,可以設置該參數提高吞吐量。

注意,RabbitMQ只支持通道級別的prefetch-count,不能基於連接或大小進行預取。


Message Attributes and Payload

在AMQP模型中消息有很多屬性,AMQP定義的一些屬性是十分普遍的,應用程序開發者不必去考慮屬性的確切名稱。這裏有一些例子:

  • Content type
  • Content encoding
  • Routing key
  • Delivery mode(persistent or not)
  • Message priority
  • Message publishing timestamp
  • Expiration period
  • Publisher application id

有些屬性被AMQP代理服務器使用,但更多的屬性是被接收它們的應用程序使用。有些屬性時可選的比如headers,它們跟HTTP的X-Headers屬性十分相似。消息的屬性是在消息被髮送時設置的。

AMQP消息也有一個有效負載(它們攜帶的數據),AMQP服務器通常將它們視爲一個不透明的字節數組。服務器不會檢查或更改這個負載。有時消息只包含了屬性信息但是沒有數據,爲了將結構化數據作爲消息的有效負載進行發送,使用一些如JSON,Thrift,Protocol Buffers 和 MessagePack等不同序列化格式對數據進行序列化是十分常見的。AMQP通常使用content-typ和content-enconding屬性來設置消息,但這只是按照慣例進行設置。

在消息被髮送時設置了持久化屬性,這使得AMQP服務器將會把這類型的消息保存到硬盤。當服務器重啓時需要確保接收到的持久化消息不會丟失。簡單地說,比如講消息發送到一個持久化的交換機或者消息被路由到一個持久化的隊列,這種情況下都不使該消息得到持久化,消息是否持久化完全依賴於消息自身屬性的設置。當發送持久化的消息時,會影響服務的性能(就像數據持久化,持久化會對性能造成一定的影響)。


Message Acknowledgements

由於網絡是不可靠的並且應用程序也會崩潰,所以經常需要某些處理確認。有時僅需要確認消息已經被接收到了,有時需要確認消息已經被消費者處理了,比如,證實有強制性的消息已經被持久化到數據庫或者被索引。

這種情況是普遍存在的,所以AMQP協議有一個稱爲消息確認(有時也指acks)的內置功能,消費者使用該功能來確認消息的成功發送或成功處理。如果應用程序崩潰(當連接斷開時AQMP代理服務器將會發現)或服務器期待的消息的確認消息沒有接收到,這時,消息將被重新入隊派發(如果有其他消費者存在,會立即將消息發送給其他消費者)。

在協議中內置確認機制可以幫助開發人員建立更具健壯性的軟件。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章