サブスクライバーに障害が発生した場合に EMS パブリッシャーに通知する方法の答えを見つけようとしています。パブリッシャー→EMSサーバー→サブスクライバーの場合、サブスクライバーに障害が発生した場合は、パブリッシャーに通知して対処する必要があります。耐久性/永続性については気にしません。私の重要性は時間です。取引システムでは、成行注文をサブスクライバーに送信し、サブスクライバーがそれを取引所に送信する場合、それが失敗した場合、パブリッシャーに別のトピックに関するメッセージを別のサンスクライバー (別の取引所) に発行させる必要があります。どんなアイデアでも大歓迎です。
2 に答える
tibjmsadmin.jar ライブラリには、サブスクライバがいつ切断されたかを検出するメソッドが含まれています。コードを書くよりも簡単に、次のことができます。
- Hawk を使用している場合は、tibjmsadmin.hma を使用して、サブスクライバーが切断された場合の Hawk ルールを記述します。または
- モニター トピック $sys.monitor.connection.disconnect をリッスンします。メッセージの本文には、切断されたサブスクライバーが示されます。
ただし、パブリッシャーをフェイルオーバーするためのこれらの「監視」アプローチには重大な問題があります。サブスクライバーの障害を検出してパブリッシャーをリダイレクトするのにかかる時間内に、一部のメッセージが通過して無効なキューにスタックする可能性があります。1,000 万ドルの取引でこれが起こるのを期待する必要はありません。
EMS は加入者が接続されているかどうかを認識しているため、これを利用する必要があります。
「分散キュー」を使用すると、アプリケーションにロジックをコーディングして、失敗したときに新しいサブスクライバーに切り替える必要はありません。これは、メッセージを失うことなく発生し、メッセージの順序を維持します。また、ロード バランシングとフェイルオーバー ロジックをコードから除外し、JMS プロバイダーの管理設定に含めることも、優れたアーキテクチャ プラクティスです。
基本的に、複数のサブスクライバーをキューにセットアップします (各交換はサブスクライバーによって表されます)。デフォルトのアクションは、EMS がラウンドロビン方式でサブスクライバー間でメッセージの負荷を分散することです。ただし、メッセージが一度に 1 つのサブスクライバーだけに送信されるように、キューを「排他的」に設定できます。そのアクティブなサブスクライバーに障害が発生すると、メッセージは別のサブスクライバーに転送されます。
これらすべてのトピックの詳細については、EMS マニュアルを参照してください。
アクセスできるかどうかわからない場合は、QueueInfo または TopicInfo で ReceiverCount または ConsumerCount を確認してみてください。tibjms.admin パッケージが必要だと思います。公開する前にこれを照会してから、選択的に公開できますか? オーバーヘッドが何であるかわかりません。
JMS の性質上、トランザクション状態 (XA トランザクションを使用しない限り - そのすべてのオーバーヘッドを伴う) や確認応答は、EMS ブローカーを介して伝播されません。Iack は常にパブリッシャーとブローカーの間、およびコンシューマーとブローカーの間にあります。
上記に失敗した場合、役割が逆になっている別の ack トピックを試すことができますが、失敗の場合はタイムアウトになります。これが賢明かどうかはわかりません。
注文がどの取引所に送られるかを本当に気にしない場合 - トピック/キューを排他的にして、両方の消費者が消費しようとしないのはなぜですか - 最初に成功したものはすべてのメッセージを処理します - それが死んだ場合、2番目のもの(定期的に再試行する可能性があります-正常に接続する場合があります)..または、両方がキューから注文を処理できるようにします-メッセージは単一の消費者によってのみ処理されることに注意してください...
あなたの注文フローでは、分離されたメッセージング バスの利点が本当にわかりません...私には意味がありません..