他の人が、公式の 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)
ラップConnection
とChannel
クラスは、再接続ロジックを処理するクラスであり、消費者はWrappedChannel
クラスについて知る必要があるだけです。接続に失敗した場合、 は接続WrappedConnection
の再確立を処理し、接続されると、WrappedConnection
は自動的に新しいチャネルを作成してコンシューマーを登録します。
長所: 機能します。これは、実際に現在使用しているソリューションです。
短所: ハックのように感じます。これは、基盤となるライブラリでよりエレガントに処理する必要があると思います。
多分もっと良い方法がありますか?API ドキュメントでは、障害のある接続からの回復についてはあまり説明されていません。どんな入力でも大歓迎です:)