14

他の人が、公式の RabbitMQ Java クライアント ライブラリを使用して、障害のある接続から回復する方法を知りたいです。アプリケーションサーバーをRabbitMQクラスターに接続するためにそれを使用しており、接続障害から回復するためにいくつかの異なる方法を実装しましたが、どれも適切ではありません.

次の疑似アプリケーションを想像してください。

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 ドキュメントでは、障害のある接続からの回復についてはあまり説明されていません。どんな入力でも大歓迎です:)

4

2 に答える 2

6

RabbitMQ メーリング リストでいくつかの良い回答を得て、基本的に上記のソリューション C を提案しました。

ソリューション C)

ラップ接続およびチャネル クラスは、再接続ロジックを処理するクラスです。消費者は、WrappedChannel クラスについてのみ知る必要があります。接続が失敗すると、WrappedConnection は接続の再確立を処理し、接続されると、WrappedConnection は自動的に新しいチャネルを作成し、コンシューマーを登録します。

長所: うまくいきます - これは実際に私たちが現在使用しているソリューションです。

短所: ハックのように感じます。これは、基盤となるライブラリでよりエレガントに処理する必要があると思います。

これは、Java クライアントの上に構築された 2 つのクライアント (Langohr と March Hare) が行うことです。これはハックではありませんが、必要な回避策です。これは、接続の回復が現在 Java クライアントによって実行されていないためです (私に言わせれば、これはコア機能のはずです)。

したがって、これは実行可能なアプローチです。

Lyra も見てみましょう: https://github.com/jhalterman/lyra

MK

ソフトウェア エンジニア、Pivo​​tal/RabbitMQ

と:

ピーターさん、こんにちは。

解決策 C は実際にはかなり合理的です。ネットワーク障害やクラスター パーティションから保護しようとしている場合は、同じサーバーへの複数の接続を使用してもあまりメリットはありません。1 つの接続が切断された場合、すべての接続が切断される可能性があります。接続/チャネルのラップと回復は正常に機能します。Michael が述べたように、リソースの回復に関連するさまざまなコーナー ケースを処理する Lyra もチェックしてください。

乾杯、ジョナサン

ここでスレッド全体を読んでください:

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

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

于 2013-11-06T17:09:00.603 に答える