クライアント アプリケーションのインスタンスが多数あります。これらのクライアントは、メッセージングを介してサーバー アプリケーションに要求を送信し、応答を受け取ります。通常、応答は一時キューを使用して送信されます。
残念ながら、一時的なキューやトピックの概念がない Stomp プロトコルを使用する必要があります。(メッセージブローカーにはありますが)
元の要求者だけが返信を受け取るようにする最善の方法は何ですか? この不幸な状況に対するベストプラクティスはありますか?
クライアント アプリケーションのインスタンスが多数あります。これらのクライアントは、メッセージングを介してサーバー アプリケーションに要求を送信し、応答を受け取ります。通常、応答は一時キューを使用して送信されます。
残念ながら、一時的なキューやトピックの概念がない Stomp プロトコルを使用する必要があります。(メッセージブローカーにはありますが)
元の要求者だけが返信を受け取るようにする最善の方法は何ですか? この不幸な状況に対するベストプラクティスはありますか?
複数のリクエスターが同じキューで応答をリッスンする場合の通常の解決策は、相関 ID を使用してメッセージを選択することです。クライアント側では、次のようになります。
サーバー側では、次のようになります。
コンシューマーは、セレクターを次のように設定しますactivemq.selector:JMSCorrelationID=
。
ブローカはグローバルに一意であると想定されるメッセージ ID を作成するため、それを相関 ID として使用するパターンにより、各リクエスタが独自の値を指定できる場合に発生する可能性のある衝突が防止されます。
このパターンを JMS で実装する最良の方法 (とにかく私が見つけた) は、応答メッセージ用に事前構成されたトピックを作成し、応答メッセージで相関セレクターを使用して、クライアントが正しいトピックを取得できるようにすることです。
より詳細には、これは ( を使用してsetJMSCorrelationID()
) リクエスト メッセージにランダム ID を設定し、そのメッセージをリクエスト キューに置くことを意味します。その要求メッセージのコンシューマはそれを処理し、応答メッセージを作成し、応答メッセージに同じ相関 ID を設定して、応答トピックに配置します。一方、クライアントは、期待する相関 ID を指定するセレクター式を使用して応答トピックをリッスンしています。
危険なのは、クライアントが応答メッセージをリッスンする前に応答メッセージが送信されることです。トピックではなく、応答用に事前設定されたキューを使用してみることができますが、トピックの方がより確実に機能する傾向があることがわかりました (選択した JMS プロバイダーは HornetQ です。マイレージは異なる場合があります)。
これはすべて、JMS が要求/応答モデルに非常に適していないことを示しています。API はそれを適切にサポートしていません。これは、JMS のユースケースではなかったので、驚くことではありません。
コンピューティング グリッド (Terracotta、Gigaspaces、Infinispan など) のようなものを使用すると、より良い結果が得られる可能性がありますが、それは実際には選択肢ではありません。