一、消息持久化
在消息發佈前,通過把它的投遞模式(delivery mode)選項設置爲2來把消息標記爲持久化。
1.1 消息持久化過程:
當發佈一條持久化消息到持久化交換器上時(帶有durable=true的exchange),Rabbit會在消息提交到日誌文件後
才發送響應。如果這條消息路由到了非持久化隊列,它會自動從持久化日誌中移除,並且無法從服務器重啓中恢復。
如果從持久化隊列中消費了一條持久化消息的話(並且確認了它),RabbitMQ會在持久化日誌中把這條消息標記
爲等待垃圾收集。如果在消費持久化消息前,RabbitMQ重啓的話,服務器會自動重建交換器和隊列以及綁定,重新
把持久化日誌文件中的消息投遞到合適的隊列或者交換器上。
由於消息發佈操作不返回任何信息給生產者,那怎麼知道服務器是否已經持久化到磁盤呢?服務器可能會把消息在寫入磁盤
前就宕機了,消息可能因此而丟失。那如何確保消息持久化到磁盤了呢?
1.2 消息持久化方式
1.2.1、開啓事務模式(transaction)
當繼續處理其它消息前,必須確保代理接收到了消息(並且已經將消息路由到所有匹配的隊列),我們需要將這些
行爲包裝到一個事務當中。在AMQP中,在把信道設置成事務模式後,通過發送多個AMQP命令確保消息路由到所有
匹配的隊列時,只有所有的命令都執行成功,事務纔可以提交。開啓事務,意味着生產者的消息之間產生同步,這會使
Rabbit的性能大大降低。
1.2.2、發送方確認模式。
將信道設置成confirm模式,而且只有重新創建信道才能關閉該設置。一旦信道進入confirm模式,所有在
信道上發佈的消息都會被分配一個唯一的ID號(從1開始)。一旦消息被投遞給所有匹配的隊列後,信道會
發送一個確認給生產者(包含消息的唯一ID)。這使得生產者知曉消息已經安全到達目的隊列了。如果消息和
隊列是可持久化的,那麼確認消息只會在隊列將消息寫入磁盤後纔會發出。發送方確認模式最大的好處是它們
是異步的。一旦發佈了一條消息,生產者就可以在等待確認的同時繼續發送下一條。當確認消息最終收到的時候,
生產者應用的回調方法就會觸發來處理該確認消息。如果Rabbit發生了內部錯誤從而導致了消息的丟失,Rabbit
會發送一條nack(未確認)消息,來告訴生產者該消息已丟失。由於沒有消息回滾的概念(相對於事務),因此
發送方確認模式更加輕量級。
二、發送到持久化的交換器。
設置交換器(exchange)的durable屬性設置爲true。
三、路由到持久化隊列
設置隊列(Queue)的durable屬性設置爲true。