2

与えられた:

  • JMS メッセージ キュー。
  • (データベースから) 定期的にそのキューにメッセージを入れるタイマー サービス。
  • キューから読み取る JEE6 メッセージ駆動型 Bean。
  • タイマー サービスとメッセージ駆動型 Bean は、異なるデプロイメント ユニットの一部です。

問題:

メッセージが処理中である限り、ワークフローの状態を壊さずにメッセージ駆動型 Bean をアンデプロイすることはできません。そのため、最初にタイマー サービスを停止し、すべてのメッセージが終了するまで待ちます。

その動作を自動化する方法はありますか? または、タイマー サービスがまだ実行されている場合、アンデプロイを防ぐことは可能ですか? 現在、JBoss 4.2.3 を使用しています。

非解決策:

  • 複数の部門が関与するため、展開ユニットをリファクタリングします。
  • システムのクラッシュはカバーされず、防弾ソリューションには回復戦略が含まれている必要があることを知っています.
4

1 に答える 1

2

デプロイされた各 MDB には、JMX 管理インターフェース MBean があります。この MBean の ObjectName はデプロイメントによって異なります (JBoss のバージョン間でも異なる場合があります)。JBoss 4.3 を使用しており、ObjectName の形式は次のとおりです。

Domain Name:    jboss.j2ee
service:    EJB3
name:   <MDB Name>
ear:    <EAR Name>  (if applicable)
jar:    <JAR Name>

タイマー サービスが JBoss ServiceMBean の場合、JBoss @Depends("the timer service ObjectName")アノテーションを使用して、MDB をタイマーに依存させることができます。これにより、MDB が開始する前にタイマー サービスが強制的に開始されます (タイマー サービスに開始後の遅延を設定することが望ましい) が、さらに重要なこと、アンデプロイ時に逆のことが発生し、タイマー サービスが最初に停止し、次に MDB が停止することです。

それが機能する場合、順序付けは処理されますが、タイマーの実行中に MDB をアンデプロイしないように強制することはできないと思います。アプリケーションの詳細がこれをサポートしていない可能性がありますが、この問題を解決する方法の 1 つは、タイマーとメッセージ プロセッサを本質的に 1 つにバインドするJBoss Quartz JCA Inflow Adapterを使用することです (MDB に似ていますが、タイマー イベントを受け取ります)。メッセージではなく)、2 つのコンポーネント間の依存関係に取り組む必要がなくなります。

================================ 試行 #2 =============== =================

では、フィード キューの深さが 0 を超えている間に MDB が停止しないようにします。このアプローチは、JBoss に非常に固有のものですが、うまくいくはずです。

  1. MDB Delegate MBean の状態変化をリッスンするJMX NotificationListenerを実装します。
  2. JMX NotificationFilterを実装して、リッスンする特定のイベントを絞り込むこともできます。
  3. 探している状態の変化は属性Stateにあり、探している遷移は3 --> 1 (開始 --> 停止中)です。
  4. [このバージョンの] JBoss の JMX 通知は同期的に発行され、通知リスナーが戻るまでブロックされます。リスナーがこの通知を受信したら、MDB のフィード キュー MBean でポーリング ループを開始します (JBoss Messaging を使用しているかどうかは尋ねていませんが、使用していると仮定します)。MessageCountが > 0の間、ポーリングを続けます。キューのメッセージ数がゼロになると、リスナーが返され、MDB が停止します。
  5. ポーリング ループに短いスリープを追加し、ポーリング タイムアウトを追加してください (問題が発生した場合に備えて)。
  6. また、メッセージ カウントに表示されない可能性のあるコミットされていないメッセージが転送中にある場合に備えて、少なくともn回のポーリング ループでメッセージ カウントが 0 になるまで返さないことを検討することもできます。

肝心なのは、属性変更リスナーが呼び出されている間、メッセージは引き続き処理されるということです。属性変更リスナーが戻ると、MDB の停止が続行されます。

JMS 実装がローカルの VM 内 JBoss Messaging である場合、キュー メッセージ カウントはキューの管理 MBean で利用できます。その他のセットアップでは、独自の JMS API 呼び出しを行ってキューのメッセージ カウントを取得する必要がある場合があります。または、より強引なアプローチを使用して、単純に JMS QueueBrowserを要求し、メッセージ数をカウントすることもできます。

于 2011-04-28T13:38:16.407 に答える