4

ActiveMQ クライアントを使用する .NET サービスがあります。メッセージを消費するために、トランザクション接続を使用して MessageListener を実装しました。

ときどき、メッセージがキューに入れられた順序とは異なる順序でメッセージを受け取ることがあります。

MessageListner を使用するのは間違っていましたか? メッセージの順序を維持する方法はありますか?

参考までに: メッセージをキューに入れる 1 つのプロデューサーと、キューからメッセージを取り出す 1 つのコンシューマーがあります。

4

4 に答える 4

1

詳細情報: 私が呼び出しているサーバーはサード パーティであり、送信するメッセージを制御することはできません。メッセージ ID に基づいて、それらが正しい順序で配置されていることはわかっています。また、このシステムでは ACK と Acknowledge に違いがあります。元のメッセージが「送信」キューに置かれると、ACK が受信されます。次に、応答の「受信」キューを監視します。私は通常、「承認」の後に「合格」または「不合格」を受け取ります。これらのメッセージの相関 ID は、ACK からのメッセージ ID です。

私はもともとメッセージ リスナーを使用し、OnMessge イベントに応答していました。この方法を使用すると、メッセージが非同期で配信されるため、特定の順序で配信されないことに気付き、このアプローチを断念しました。そこで、タイマー (System.Threading.Timer) を使用してポーリングし、consumer.Receive() を呼び出して一度に 1 つのメッセージを取得するようにコードを変更しました。これは私が望むように機能します。

サービスの開始時に一度コンシューマーを開き、メッセージを継続的にポーリングします。

于 2009-01-19T17:22:55.177 に答える
1

順序を維持するために何もする必要はありません。これは、メッセージ キューがユーザーに代わって行うことの 1 つです。キューをリッスンしている単一のコンシューマーがあり、メッセージを順不同で処理している場合、バグを発見したか、メッセージが思った順序でキューに入れられていないと思います。

また、役立つかもしれないActiveMQ FAQからのこの質問があります。

編集: duffymo's answerに関するコメントを読むと、少しオーバーエンジニアリングしているように見えます。一般に、ActiveMQ、MQ Series、joram などのメッセージ キューには 2 つの特徴があります。キューに入れられたのと同じ順序でメッセージを配信することと、メッセージ配信を保証することです。別の ACK メッセージを送信するのは冗長です。これは、データベース トランザクションをコミットし、同じ情報をクエリして、データベースに実際に格納されていることを再確認することに少し似ています。

そうは言っても、サーバーはマルチスレッド化されていますか? その場合、ACK をキューに入れるに応答をキューに入れることができる可能性があります。

于 2009-01-09T00:42:31.727 に答える
0

ジェイソンが今言ったことすべて。その他、気をつけたいことをいくつか。多くのメッセージに対してコンシューマを開いたままにしていますか? いくつかのメッセージのコンシューマーを作成してから閉じていませんか? コンシューマーを閉じるだけで、コンシューマーに関連付けられたメッセージがキューに戻され、順序が乱れる可能性があります。

ロールバックに関連していますか?(トランザクションをロールバックしていますか?)。

最後に、Resequencerを使用して順序を変更することで、常に順序を確保できます。

于 2009-01-09T09:39:45.603 に答える
0

メッセージの順序が重要なのはなぜですか? MessageListener は気にする必要はありません。

応答を特定の要求と一致させるために相関 ID が必要な場合、それは別の問題です。そうですか?

于 2009-01-09T00:19:43.427 に答える