3

クラスタ化された環境に JBoss-Server の複数のインスタンスがあります。バックグラウンド タスクには、登録されているすべてのジョブを管理するグローバル キューが利用可能です。このキューでは、各ノードに単純なリスナー (MDB) があり、着信メッセージを管理します。このリスナーは、シングルトン Bean の手動ルックアップ (インジェクションなし) を実行し、事前定義されたメソッドを開始します。これまでのところすべて正常に動作していますが、シングルトン Bean のメソッドは、状況によっては利用できない他の (シングルトン サービスではない) を使用しています。たとえば、ノードが再起動され、キューにメッセージが残っている (まだ処理されていない) 場合、メッセージはリスナーによって取得され、それ以降のすべての Bean は null になるため、ジョブは NPE を生成します。メッセージが取得された後、JMS-Listener で遅延時間を定義することは可能ですか?

MDB プロパティの "DeliveryActive" を false に設定し、完全なデプロイ後に Bean を開始することもできます。これをプログラムで(jmx-consoleではなく)簡単に実行できる方法はありますか?これに関するマニュアルを見つけた場合は、手動の jndi ルックアップにリダイレクトされます。アノテーションごとに Bean を注入して startDelivery() を呼び出すことが可能でなければならないと思いますか? アプリケーションでこれを行うのに適した場所はありますか?

別のヒントとして、application.xml の initialise in order プロパティに移動します。これは、問題が JBoss の展開順序に関連している可能性があるためです (一部の EJB はリスナーよりも後で使用可能になります)。ただし、JBoss 6.0にバグがあり、アップグレードすると6.1. オプションではありません。多分これのためのウォークスルーがありますか?

問題が十分に説明されていることを願っています。それ以外の場合は、さらに情報を求めてください。

前もってありがとう、ダニー

追加情報:

  • JBoss 6.0.0 最終版
  • HornetQ 2.2.5 Final (JBoss のデフォルト バージョンにバグがあるため、更新済み)

リスナー:

@MessageDriven(activationConfig =
    {
            @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
            @ActivationConfigProperty(propertyName = "destination", propertyValue = "/queue/SchedulerQueue")
    })
public class SchedulerQueueListener implements MessageListener {
...
@Override
public void onMessage(Message message) {
   ...
   service = (IScheduledWorkerService) new InitialContext().lookup(jndiName);
   EJobResult eJobResult = service.executeJob(message);
   ...
}

サンプル ワーカー:

@Singleton
@LocalBinding(jndiBinding = SampleJobWorkerService.JNDI_NAME)
public class SampleJobWorkerService implements IScheduledWorkerService {

...
    @EJB(name = "SampleEJB/local")
    private ISampleEJB sampleEjb;
...
    @Override
    public EJobResult executeJob(Message message) {
    int state = sampleEjb.doSomething(message.getLongProperty(A_PROPERTY));
    }

この場合、sampleEjb - メンバーは時々 null になります

4

2 に答える 2

1
  1. 回避策として、EJB を MDB から直接呼び出す代わりに、タイムアウトのあるタイマーを作成して遅延を発生させることができます。そのため、実行に多少の遅れが生じます。

    タイマーのタイムアウト メソッドでは、シングルトン EJB を呼び出すことができます。これは、場合によっては、他の非シングルトン EJB を呼び出します。

  2. JBoss 固有: 送信前にメッセージ オブジェクトでプロパティの設定を試すことができます。

    msg.setLongProperty("JMS_JBOSS_SCHEDULED_DELIVERY", (current + delay));

    他の代替手段は_JBM_SCHED_DELIVERY.

編集 :

最初の部分では、JMS と EJB にまたがる可能性のある JTA トランザクションを使用できます。したがって、フェイルオーバーとその他の処理はそれに応じて処理される場合があります。

メッセージ オブジェクトの再配信の遅延を増やすこともできます。

<address-setting match="jms.queue.someQueue">
        <redelivery-delay>5000</redelivery-delay>
</address-setting>
于 2012-02-13T19:54:44.820 に答える
0

私も今、同じように悩んでいます。

シングルトン Bean でEJB 3 スタートアップ Bean アノテーション を使用して、メッセージ リスナー@Startupでメソッドを呼び出すことをお勧めします。startDelivery

于 2012-05-23T13:27:27.110 に答える