web-dev-qa-db-ja.com

JMSでメッセージの順序を処理する方法は?

Javaで記述されたクライアントサーバーアプリケーションを確認しています。サーバーはJMSメッセージを受信して​​処理しますが、メッセージが予期しない順序で届く可能性があり、注文メッセージの前にキャンセルが到着する可能性があります。そのような場合をどのように処理しますか?あなたはmdbでそれをしますか?

この種のシナリオの戦略またはパターンは何ですか?

24
user271858

私の知る限り、これは「アウトオブオーダー」配信と呼ばれ、JMSシステムのサービス品質(QoS)属性の一部です。これはJMS仕様の一部ではないと思いますが、一部のプロバイダーはおそらくそれをサポートしています。これは、使用する特定のJMS実装によって異なります。

ただし、JMSは、負荷を分散する方法で複数のコンシューマーにメッセージを分散することを目的としていることに注意してください。メッセージを順序付けられた方法で配信する必要がある場合、これは不可能です。基本的に、メッセージ配信のシリアル化につながり、メッセージを同時に処理できませんでした。

wikipedia 私よりもいいと言っています:

JMSキュー送信され、読み取られるのを待機しているメッセージを含むステージング領域。名前キューが示唆するものとは異なり、メッセージは送信された順序で配信される必要はないことに注意してください。メッセージ駆動型Beanプールに複数のインスタンスが含まれている場合、メッセージを同時に処理できるため、後のメッセージが前のメッセージよりも早く処理される可能性があります。 JMSキューは、各メッセージが1回だけ処理されることのみを保証します。

その場合、帯域外キャンセル要求をJMSで実現するのは簡単ではありません。 2つのアイデア:

  • 各メッセージに対応するチケットをデータベースに保存すると、メッセージを簡単にキャンセルできます。メッセージが配信されると、MDBは対応するチケットがまだ有効かどうかを確認します。はいの場合はさらに進み、そうでない場合はメッセージをドロップします。
  • MDBプールサイズを1に設定してみてください。たぶんこの場合、配達は注文されます。プールサイズの変更はアプリです。サーバー固有ですが、それらのほとんどはBeanごとのプールサイズをサポートしています。

それ以外の場合は、 メッセージストア パターンを見てください。とにかく、 [〜#〜] eai [〜#〜] Webサイトを確認する価値があります。

16
ewernli

順不同のメッセージに対処できれば、システムははるかに柔軟になります。過去にこれを解決するために使用したパターンは、遅延キューを使用することです(金融業界で1日あたり800万通のメッセージを処理するシステムで)。

あなたの例では、まだ受け取っていない注文の削除を受け取った場合、それを一定期間遅らせて再試行します。削除を求められている注文についてまだ何も知らない場合は、なんらかのエラーが発生します(元の送信者に返信する、特別なエラーキューにメッセージを送信するなど)。

遅延キューの実装に関しては、これは、遅延するメッセージを受け入れることができるサービスを備えた別のJMSキューである可能性があります。次に、遅延メッセージを定期的に読み取り、遅延期間が経過したかどうかを確認して、メッセージを元の宛先キューに再送信します。

8
SteveD

次に、EAIサイトと、それが基づいている本(MOMとMOMパターンに関する素晴らしいテキスト)を確認するためのアドバイスを示します。

個人的には Resequencer を調査します。

6
p.marino

mdbが受信するメッセージのシーケンスを保証する方法は?は、サーバー側の同様のトピックについてであり、誰かがそれを示しています- ActiveMQ 順序を維持するソリューションがある可能性があります。私はこれがそれをverdor特有にすることを推測します。

2
simgineer