8

私はいくつかのモジュールで構成されるアプリケーションに取り組んでいます。これらのモジュールの 1 つで、誰かがトピックにメッセージを発行するトピック プロデューサーを作成しましたが、このモジュールにはメッセージをデキューするトピック コンシューマーがありません。トピック プロデューサーは、 を使用して、time-to-live プロパティを 300000 ミリ秒に設定しsetTimeToLive()ます。

コンシューマが存在しない場合、メッセージは 300000 ミリ秒以内に期限切れになり、割り当てが解除されると予想されます。

アプリケーションは Tomcat 6.0.36 にデプロイされ、外部の ActiveMQ サーバーを使用してキューとトピックを処理します。

トピック設定の [MBeans] タブで Java VisualVM を使用して ActiveMQ を監視すると、変数 "Enqueue Count" が大きくなっていることがわかりますが、これらのメッセージで有効期限の設定が有効になっているかどうかわかりません。カウンター「ExpiredCount」が増加することを期待していましたが、それでも 0 に固定されたままです。

これらのメッセージがまだメモリに残っているのか、それとも割り当てが解除されているのかを理解する方法はありますか?

どうもありがとうございました!

編集:

内部のglassfish 3.1をサーバーとして使用してnetbeans 7.3でj2eeチュートリアルの例を使用していくつかのテストを行い、jvisualvmでそれを監視し、すべてapiが言うように動作します:

JMS API には、トピックを参照するメカニズムはありません。通常、メッセージは表示されるとすぐにトピックから消えます。メッセージを消費するメッセージ コンシューマーが存在しない場合、JMS プロバイダーはメッセージを削除します。永続的なサブスクリプションでは、メッセージ コンシューマーがアクティブでない間、メッセージをトピックに残すことができますが、メッセージを調べる機能はありません。

グラスフィッシュがactiveMQ内で使用していることを読んだので、これがスタンドアロンのActiveMQサーバーでも有効であることを願っています。

編集を終了します。

4

1 に答える 1

6

堅牢な JMS アプリケーションの作成からの引用:

5.1.4 メッセージの期限切れを許可する
[...]
メッセージが発行されると、指定されたtimeToLiveが現在の時刻に追加され、有効期限が与えられます。指定された有効期限までに配信されなかったメッセージは破棄されます。

のソースからの別の引用javax.jms.Message#getJMSExpiration()

メッセージの有効期限に達すると、プロバイダーはメッセージを破棄する必要があります。[...]
クライアントは期限切れのメッセージを受信すべきではありません。ただし、JMS API は、これが起こらないことを保証しません。

したがって、永続的でないサブスクライバーの場合:

  1. サーバーは、接続されている各サブスクライバーにメッセージを送信します。メッセージの有効期限の値は、「現在の時刻 + TTL」に設定されます。切断されたサブスクライバーは何も受信しません。
  2. メッセージがまだ期限切れになっていない場合、接続されたクライアントはメッセージを正常に受信します。
  3. 接続されたクライアントがメッセージを受信するまでに時間がかかりすぎる (メッセージの有効期限が切れている) 場合、メッセージはサーバーによって破棄されるか (おそらく、サーバーがまだメッセージをクライアントのバッファーにプッシュしていない場合)、受信できる可能性があります (おそらく、メッセージはすでにクライアントのバッファにあります)。

したがって、あなたの場合、消費者がいない場合、メッセージはおそらくまったく保存されません。 Enqueue カウントが増加し、Expired Countは 0 のままです。Expiredカウントは、接続されている (しかしアイドル状態の) サブスクライバーの場合にのみ増加する必要があります。

キューのサイズを見つける方法からの引用

Enqueue Count - 前回の再起動以降にキューに送信されたメッセージの総数
Expired Count - 期限切れのために配信されなかったメッセージの数

注: JBoss 7 を使用したテストでは、この場合、メッセージがクライアントに表示されないことが示されています。

于 2013-08-29T11:01:19.200 に答える