我很想知道其他人如何使用官方RabbitMQ java客戶端庫來處理從錯誤連接中恢復的問題。我們正在使用它將我們的應用程序服務器連接到我們的RabbitMQ集羣,並且我們已經實現了幾種不同的方式來從連接故障中恢復,但是他們中的一些人感覺非常正確。如何處理使用RabbitMQ java客戶端庫從故障連接中恢復?
想象一下這樣的模擬應用:
public class OurClassThatStartsConsumers {
Connection conn;
public void start() {
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("someusername");
factory.setPassword("somepassword");
factory.setHost("somehost");
conn = factory.newConnection();
new Thread(new Consumer(conn.createChannel())).start();
}
}
class Consumer1 implements Runnable {
public Consumer1(Channel channel) {
this.channel = channel;
}
@Override
public void run() {
while (true) {
... consume incoming messages on the channel...
// How do we handle that the connection dies?
}
}
}
在現實世界中,我們有幾百個消費者。那麼,如果連接死亡會發生什麼?在上面的例子中,Consumer1無法恢復,當連接關閉時,Channel也關閉,我們無法恢復的狀態。所以,讓我們看看一些方法來解決這個問題:
解決方案A)
讓每一個消費者都有自己的連接,並登記在連接死亡觸發的事件,然後重新連接處理。
優點:它的工作原理
缺點:
- 因爲我們有很多的消費者,我們可能不希望很多 連接。
- 我們有可能會擁有 重新連接到兔子大量的重複的代碼和處理重新連接
溶液B)
讓每個消費者使用相同的連接,並訂閱它的連接故障事件。
優點:比解決方案A
缺點更少的連接:由於連接被關閉,我們需要重新打開/替換它。 java客戶端庫似乎沒有提供重新打開連接的方式,所以我們必須用新連接來替換它,然後以某種方式通知所有消費者關於這個新連接,並且他們將不得不重新創建渠道和消費者。再一次,我不想在消費者身上看到很多邏輯。
解決方案C)
裹Connection
和Channel
類是處理重新連接邏輯類,消費者只需要瞭解WrappedChannel
類。在連接失敗時,WrappedConnection
將處理重新建立的連接,一旦連接,WrappedConnection
將自動創建新的通道並註冊使用者。
優點:它的工作原理 - 這實際上是我們今天使用的解決方案。
缺點:這感覺就像是黑客,我認爲這是應該由底層庫更優雅地處理的東西。
也許有更好的方法? API文檔沒有涉及從錯誤連接恢復的問題。任何輸入讚賞:)
你可以給出提示如何編碼它。由於似乎沒有回調,因此我們可以恢復所有通道,隊列和綁定。你能告訴我,我應該如何包裹連接? – jeevs
您必須包裝連接和頻道,一旦它斷開連接,無法恢復頻道,因此您必須創建一個新頻道。 –