RabbitMq的一些概念,持久化、隊列排他、自動刪除、消息確認機制、消息ACK、消費消息的模式

1、隊列持久化的概念

隊列的聲明默認是存放到內存中的,若是rabbitmq重啓會丟失,若是想重啓以後還存在就要使隊列持久化,保存到Erlang自帶的Mnesia數據庫中,當rabbitmq重啓以後會讀取該數據庫。數據庫

2、排他

簡單理解就是在鏈接關閉時是否會刪除隊列(不管隊列中有沒有消息) 性能

3、自動刪除

當隊列中有消息時,不管是否排他,關閉鏈接都不會刪除隊列,此時消費者消費完消息後再斷開消費者,隊列會被自動刪除。(這裏若是有多個消費者消費同一個隊列,則須要全部消費者都斷開後才能自動刪除) spa

4、消息確認機制 Message acknowledgment

在實際應用中,可能會發生消費者收到Queue中的消息,但沒有處理完成就宕機(或出現其餘意外)的狀況,這種狀況下就可能會致使消息丟失。爲了不這種狀況發生,咱們能夠要求消費者在消費完消息後發送一個回執給RabbitMQ,RabbitMQ收到消息回執(Message acknowledgment)後纔將該消息從Queue中移除;若是RabbitMQ沒有收到回執並檢測到消費者的RabbitMQ鏈接斷開,則RabbitMQ會將該消息發送給其餘消費者(若是存在多個消費者)進行處理。這裏不存在timeout概念,一個消費者處理消息時間再長也不會致使該消息被髮送給其餘消費者,除非它的RabbitMQ鏈接斷開。 這裏會產生另一個問題,若是咱們的開發人員在處理完業務邏輯後,忘記發送回執給RabbitMQ,這將會致使嚴重的bug——Queue中堆積的消息會愈來愈多;消費者重啓後會重複消費這些消息並重復執行業務邏輯…。pub message是沒有ack的。線程

消息一旦被消費者接收,隊列中的消息就會被刪除。RabbitMQ怎麼知道消息被接收了呢?接口

若是消費者領取消息後,還沒執行操做就掛掉了呢?或者拋出了異常?消息消費失敗,可是RabbitMQ無從得知,這樣消息就丟失了!rabbitmq

所以,RabbitMQ有一個ACK機制。當消費者獲取消息後,會向RabbitMQ發送回執ACK,告知消息已經被接收。 隊列

5、消息ACK的兩種狀況

  • 自動ACK
    • 消息一旦被接收,消費者自動發送ACK 若是消息不過重要,丟失也沒有影響,那麼自動ACK會比較方便
  • 手動ACK
    • 消息接收後,不會發送ACK,須要手動調用 若是消息很是重要,不容丟失。那麼最好在消費完成後手動ACK,不然接收消息後就自動ACK,RabbitMQ就會把消息從隊列中刪除。若是此時消費者宕機,那麼消息就丟失了。 

6、Rabbitmq消費消息的模式

rabbitmq的消費模式分爲兩種: 推(Push)模式和拉(Pull)模式。推模式採用Basic.Consume進行消費,而拉模式則是調用Basic.Get模式。 內存

  • Push模式

  • mq主動將消息推送給消費者(消費者需提供一個消費接口)
  • mq屬於主動方,消費者屬於一種被動消費,一旦有消息到達mq,會觸發mq推送機制,將消息推送給消費者,無論消費者處於何種狀態。
  • 優勢:
    • 消費者代碼較少:對於消費者來講,只需提供一個消費接口給mq便可;mq將接收到的消息,隨即推送到指定的消費接口
    • 消息實時性比較高:對於消費者來講,消息一旦到達mq,mq會當即推送給消費者
  • 缺點:
    • 消費者屬於被動方,消息量比較大時,對消費者性能要求比較高;若消費者機器資源有限,可能會致使壓力過載,引起宕機的狀況。
    • 對消費者可用性要求比較高:當消費者不可用時,會致使很push失敗,在mq方須要考慮至少推送成功一次。
  • Pull模式 

  • 消息消費的過程:
    • 消費端採用輪詢的方式,從mq服務中拉取消息進行消費
    • 消費完成通知mq刪除已消費成功的消息
    • 繼續拉取消息消費
  • 對於消費者來講,是主動方,能夠採用線程池的方式,根據機器的性能來增長或縮小線程池的大小,控制拉取消息的速度,能夠很好的控制自身的壓力。
  • 優勢:
    • 消費者能夠根據本身的性能主動控制消息拉去的速度,控制本身的壓力,不至於把本身弄跨
    • 實時性相對於push方式會低一些
    • 消費者屬於主動方,控制權更大一些
  • 缺點:
    • 消費方須要實現消息拉取的代碼
    • 消費速度較慢時,可能致使mq中消息積壓,消息消費延遲等。

7、消費模式的最佳實踐 

  • 消費者性能較好,對實時性要求比較高的,能夠採用push的方式
  • 消費者性能有限,建議採用pull的方式
  • 總體上來講,主要在於消費者的性能,機器的性能若是沒有問題,push和pull都是能夠的
相關文章
相關標籤/搜索