我想確保某些類型的消息不會丟失,因此我應該使用Confirms (aka Publisher Acknowledgements)。如果發佈者在收到ack之前終止,會發生什麼情況?
如果代理在所述 消息寫入磁盤之前崩潰,代理將丟失持久消息。在某些情況下,這會導致經紀人以令人驚訝的方式行事。
例如,請考慮以下情況:
- 客戶端發佈的持久消息持久的隊列
- 客戶端從隊列中消耗消息(指出消息是持久性和隊列耐用) ,但尚未確認,
- 代理程序死亡並重新啓動,並且
- 客戶端重新連接並開始消費消息。
此時,客戶可以合理地認爲消息 將再次遞送。情況並非如此:重新啓動導致代理丟失信息 。爲了保證持久性,一個 客戶端應該使用確認。
但是,如果使用確認,發佈者在收到確認之前發生故障,並且由於某種原因(即網絡故障)未將消息傳遞到隊列中會怎麼樣。
假設我們有一個簡單的REST端點,我們可以發佈新的COMMENTS,並且當創建一個新的COMMENT時,我們想要在隊列中發佈消息。 (注意:如果我發送一個新的COMMENT消息,但最後由於回滾而未創建消息,則無關緊要)。
CommentEndpoint {
Channel channel;
post(String comment) {
channel.publish("comments-queue",comment) // is a persistent queue
Comment aNewComment = new Comment(comment)
repository.save(comment)
// what happens if the server where this publisher is running terminates here ?
channel.waitConfirmations()
}
}
當服務器重新啓動時,通道消失,消息永遠無法傳遞。 我想到的一個解決方案是,在重新啓動後,查詢庫中最近的註釋(類似於崩潰前最後3分鐘創建的註釋?),併爲每個註釋發送一條消息並等待確認。