0

クライアントから送信された 1 つの JMS メッセージを 2 つのシステムに確実に (1 回だけ) 配信する必要があります。これら 2 つのシステムは HA 対応ではないため、私が思いついた最良の提案は次のとおりです。

  1. クライアントが投稿する単一のキューを作成する

  2. 2 つの「中間」キューを設定する

  3. クライアント キューからメッセージを読み取り、同じトランザクション内の 2 つのキューにポストするカスタム "DuplicatorMDB" を使用します。

client -> JMSDQ -> DuplicatorMDB -> Q1 -> MDB -> System1
                           \->Q2->MDB->System2

そのような既存の機能はありますか?1 つまたは両方のバックエンド システムがダウンした場合に、システムのバランスをとってシステムを安定させる適切な方法は何ですか?

アプリケーション サーバーは WebLogic 10 です。

これにはトピックを使用できません。これは、クラスター内でトピックがメッセージの重複を引き起こしすぎるためです。2 つのインスタンスがある場合、トピックを使用すると、次のようになります。

 
client->Topic-->MDB1@server1->System1
           | | \->MDB2@server1->System2
           \---->MDB1@server2->System1
            \--->MDB2@server2->System2

したがって、すべてのメッセージは System1 に 2 回、System2 に 2 回配信されます。クラスター内に 8 つのサーバーがある場合、各メッセージは 8 回配信されます。これは本当に避けたい…

最後に、テストする時間ができました。これが私が観察したことです。クラスター内に2つのノードがあります。2 つの JMS サーバー: ノード 1 の jms1、ノード 2 の jms2。分散トピック dt. 永続サブスクリプションと jms-client-id=durableSubscriber を持つ MDB。システムを開始しました: 0 メッセージ、mdb@node1 は稼働中、mdb@node2 は定期的に接続しようとしていますが、「クライアント ID、durableSubscriber が使用中」のため接続できません。予想通り。

100 個のメッセージで送信: jms1@dt メッセージの現在の = 0、メッセージの合計 = 100、現在のコンシューマー = 1 ノード 1 が 100 個のメッセージを処理したことがわかります。
jms2@dt メッセージの現在の = 100、メッセージの合計 = 100、消費者の現在の = 1 つまり、「重複した」メッセージがトピックで保留中です。

さらに 100 件のメッセージが送信され、100 件がノード 1 で処理され、200 件がノード 2 で保留されています。

node1 が再起動され、mdb@node2 が dt に再接続され、「保留中」メッセージの処理が開始されました。node2 で 200 件のメッセージが処理されました。

node1 が起動した後、mdb@node2 が接続されている間、mdb@node1 は dt に接続できません。

jms1@dt メッセージ現在 = 0、メッセージ合計 = 0、消費者現在 = 0
jms2@dt メッセージ現在 = 0、メッセージ合計 = 200、消費者現在 = 1

さらに 100 個のメッセージを送信します。100 個のメッセージすべてが node2 で処理され、node1 で破棄されていることがわかります。

jms1@dt メッセージの現在の値 = 0、メッセージの合計 = 100、消費者の現在の値 = 0
jms2@dt メッセージの現在の値 = 0、メッセージの合計 = 300、消費者の現在の値 = 1

node2 を再起動すると、mdb@node1 が dt に再接続します。再起動後、mdb@node2 は dt に再接続し、mdb@node1 は dt から切断されます。

jms1@dt メッセージ現在 = 0、メッセージ合計 = 100、消費者現在 = 1
jms2@dt メッセージ現在 = 0、メッセージ合計 = 0、消費者現在 = 1

100 個のメッセージを送信します。すべてが node2 で処理され、node1 のトピックに保存されます。

jms1@dt メッセージ現在 = 100、メッセージ合計 = 200、消費者現在 = 1
jms2@dt メッセージ現在 = 0、メッセージ合計 = 0、消費者現在 = 1

その後、node2 をシャットダウンすると、mdb@node1 がトピックに再接続した後、node1 で 100 個の「保留中のメッセージ」が処理されていることがわかります。

結果は次のとおりです。400 件のメッセージを送信し、700 件が MDB によって処理され、そのうち 300 件が重複していました。

MDB の再接続は期待どおりに機能しているように見えますが、「アクティブな」MDB をホストしているノードがダウンすると、メッセージが重複する可能性があります。

これは、weblogic JMS 実装のバグまたは機能である可能性があります。

4

3 に答える 3

1

私は Weblogic を使用したことはありませんが、ほとんどの JMS ソリューションにはキューとトピックの概念があります。JMS トピックが必要です。サブスクライバーが登録すると、トピックによってメッセージが各サブスクライバーに 1 回配信されることが保証されます。

構成の詳細

更新:クラスタ化された環境で問題が発生している場合は、すべてが適切に構成されていることを確認します ( JMS トピック クラスタリングのガイドはこちら)。クラスタリング時に Weblogic がこれほど惨めに失敗するというのは、明らかに奇妙に思えます。それでも問題が解決しない場合は、 RabbitMQなど、JMS をサポートするサードパーティの Messaging Queue を調べることができ、この問題は発生しません。

于 2009-10-17T07:12:24.743 に答える
0

これは、ESB実装が受け入れるべき種類の動作です。処理のオーバーヘッドに関しては大きな違いはありませんが、「配管」とアプリケーションコードの関心を分離することは有用です。

たまたま、WebSphere JMS実装は、そのような要件に対処するメディエーションのインストールをサポートしています。WebLogicに類似したものがあるかどうか、または関連するESB製品がオプションであるかどうかはわかりませんが、これらの機能を調査することをお勧めします。現在、単純な要件があり、コードは確かに十分ですが、いくつかのマイナーな追加要件を想像するのは非常に簡単です(その宛先に送信する前に、このフィールドをドルからポンドに変換できますか?その目的地へのこのコンテンツ...)そしてlo!あなたはあなた自身があなた自身のESBを書いていることに気づきます。

于 2009-10-17T09:53:21.493 に答える
0

[...]したがって、すべてのメッセージはSystem1に2回、System2に2回配信され、クラスター内に8台のサーバーがある場合、各メッセージは8回配信されます。これは私が本当に避けたいものです...

これは、耐久性のないサブスクリプションには適していますが、耐久性のあるサブスクリプションには適していません。耐久性を確保するために、すべてのMDBは同じconnection-idとsubscription-id(デフォルトではMDB名に基づく)を共有するため、一度に1つのMDBのみがメッセージを添付および受信できます。最初に試行するMDBは接続に成功し、他のMDBは競合を検出して失敗しますが、再試行を続けます。したがって、永続的なトピックサブスクリプションを使用することでうまくいくはずです。

于 2009-10-17T17:20:15.607 に答える