簡體   English   中英

如果發布者在收到確認之前終止,該怎么辦?

[英]What happens if a Publisher terminates before receive ack?

我想確保某些類型的消息不會丟失,因此我應該使用Confirms(aka Publisher Acknowledgements)

如果代理在將上述消息寫入磁盤之前崩潰,則它將丟失持久消息。 在某些情況下,這會導致經紀人以令人驚訝的方式行事。

例如,考慮以下情形:

  • 客戶端將持久消息發布到持久隊列
  • 客戶端使用隊列中的消息(請注意消息是持久的,隊列是持久的),但尚未確認,
  • 代理死亡並重新啟動,並且
  • 客戶端重新連接並開始使用消息。

此時,客戶端可以合理地假定該消息將再次傳遞。 情況並非如此:重新啟動已導致代理丟失消息。 為了保證持久性,客戶應使用確認。

但是,如果使用確認,發布者在收到確認之前關閉並且由於某種原因(即網絡故障)未將消息傳遞到隊列,該怎么辦?

假設我們有一個簡單的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分鍾之間創建的注釋?),然后為每個注釋發送一條消息並等待確認。

您擔心的實際上不再是RabbitMQ唯一的問題,它是分布式事務問題。 討論提供了一種合理的輕量級解決方案。 還有更嚴格的解決方案,例如兩階段提交,三相提交等,以確保在確實必要時確保數據一致。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM