1. 程式人生 > >RabbitMq-持久化

RabbitMq-持久化

自動 而且 del pre text param pla truct rop

RabbitMq-消息持久化

問題:怎樣保證消息不因生產者gg而丟失
我們知道了如何在消費者的角度保證消息不丟失,但如果生產者gg了呢,消息同樣會丟失,生產者gg後會默認丟棄所有的消息,除非告訴它某些消息是不能丟失的。

解決策略:消息持久化
使用消息持久化,將消息保存到磁盤上,而不是內存中,即使生產者gg了,後面還可以通過讀取磁盤來進行恢復。

要實現消息持久化,我們需要做兩件事:從queue與message分別來標記持久化。

①首先:從queue角度標記為持久化

註意已經申明的隊列不可以再次設置

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_task

1 boolean durable = true;
2 channel.queueDeclare("task_queue", durable, false, false, null);

②從message的角度標記持久化


我們已經標記了queue為持久化,重啟後會讀取磁盤保存的消息,那麽還需要將消息標記為持久化:通過設置MessageProperties的值為:PERSISTENT_TEXT_PLAIN

1 channel.basicPublish("", "task_queue",MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());


好了現在我們已經實現消息持久化了。

註意:消息持久化並不能完全保證消息不丟失,級生產者需要將多個message保存到磁盤上,就在保存這個時間窗口上發生了意外,消息同樣會丟失,盡管這個時間很短,但還是存在。不過話說回來,盡管這個持久化機制不能百分百地保證消息不丟失,但是做一些簡單的任務還是夠用的。

RabbitMq-持久化