問題:怎樣保證消息不因生產者gg而丟失
咱們知道了如何在消費者的角度保證消息不丟失,但若是生產者gg了呢,消息一樣會丟失,生產者gg後會默認丟棄全部的消息,除非告訴它某些消息是不能丟失的。服務器
解決策略:消息持久化
使用消息持久化,將消息保存到磁盤上,而不是內存中,即便生產者gg了,後面還能夠經過讀取磁盤來進行恢復。this
要實現消息持久化,咱們須要作兩件事:從queue與message分別來標記持久化。spa
①首先:從queue角度標記爲持久化rest
注意已經申明的隊列不能夠再次設置code
1 /** 2 * @param queue the name of the queue 3 * @param durable true if we are declaring a durable queue (the queue will survive a server restart) 若是咱們聲明一個持久隊列,則爲true(隊列將在服務器重啓後繼續存在) 4 * @param exclusive true if we are declaring an exclusive queue (restricted to this connection) 若是咱們聲明一個獨佔隊列(僅限於此鏈接),則爲true 5 * @param autoDelete true if we are declaring an autodelete queue (server will delete it when no longer in use) 若是咱們聲明一個自動刪除隊列,則爲true(服務器將在再也不使用時將其刪除) 6 * @param arguments other properties (construction arguments) for the queue 隊列的其餘屬性(構造參數) 7 */ 8 boolean durable = true; 9 channel.queueDeclare("hello", durable, false, false, null);
聲明隊列時的第二個參數,設置爲true。固然以上代碼是有問題的,由於咱們已經聲明一個hello了,並且那個hello的持久化是false的,這裏咱們須要聲明一個新的隊列:queue_taskserver
1 boolean durable = true; 2 channel.queueDeclare("task_queue", durable, false, false, null);
②從message的角度標記持久化
咱們已經標記了queue爲持久化,重啓後會讀取磁盤保存的消息,那麼還須要將消息標記爲持久化:經過設置MessageProperties的值爲:PERSISTENT_TEXT_PLAINblog
1 channel.basicPublish("", "task_queue",MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes()); 隊列
好了如今咱們已經實現消息持久化了。內存
注意:消息持久化並不能徹底保證消息不丟失,級生產者須要將多個message保存到磁盤上,就在保存這個時間窗口上發生了意外,消息一樣會丟失,儘管這個時間很短,但仍是存在。不過話說回來,儘管這個持久化機制不能百分百地保證消息不丟失,可是作一些簡單的任務仍是夠用的。
get