2013-10-30 70 views
13

我很想知道其他人如何使用官方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)

ConnectionChannel類是處理重新連接邏輯類,消費者只需要瞭解WrappedChannel類。在連接失敗時,WrappedConnection將處理重新建立的連接,一旦連接,WrappedConnection將自動創建新的通道並註冊使用者。

優點:它的工作原理 - 這實際上是我們今天使用的解決方案。

缺點:這感覺就像是黑客,我認爲這是應該由底層庫更優雅地處理的東西。

也許有更好的方法? API文檔沒有涉及從錯誤連接恢復的問題。任何輸入讚賞:)

回答

6

在RabbitMQ郵件列表上得到了一些很好的答案,基本上推薦瞭解決方案C,如上所列。

解決方案C)

繞接和通道類是處理重新連接邏輯類,消費者只需要瞭解 WrappedChannel類。在連接失敗時,WrappedConnection 處理重新建立連接,並且一旦連接 WrappedConnection將自動創建新的通道並註冊消費者。

優點:它的工作原理 - 這實際上是我們今天使用的解決方案。

缺點:這感覺就像是黑客,我認爲這是應該由底層庫更優雅地處理的東西。

這就是兩個客戶端建立在Java之上的一個 - Langohr 和March Hare - do。這不是黑客攻擊,而是圍繞 進行必要的工作,因爲連接恢復目前不由Java 客戶端執行(如果你問我,它應該是一個核心功能)。

所以這是一個可行的方法。

看看萊拉也是:https://github.com/jhalterman/lyra

MK

軟件工程師,樞紐/ RabbitMQ的

和:

喜彼得,

C液實際上是非常合理的。如果您想要防止網絡故障或集羣分區,那麼獲得 就不需要使用多個連接到同一臺服務器。如果一個連接死亡,他們都可能會。包裝和恢復 連接/通道正常工作,正如邁克爾提到的那樣,您可能還會檢查出Lyra,因爲它處理涉及 的各種角落案例,爲您恢復資源。

乾杯,喬納森

閱讀完整的螺紋位置:

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2013-October/031564.html

http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/2013-November/031573.html

+0

你可以給出提示如何編碼它。由於似乎沒有回調,因此我們可以恢復所有通道,隊列和綁定。你能告訴我,我應該如何包裹連接? – jeevs

+0

您必須包裝連接和頻道,一旦它斷開連接,無法恢復頻道,因此您必須創建一個新頻道。 –