5

JBoss 5 アプリケーションを JBoss AS 7 (7.1.1.FINAL) に移行しているときに、新しい JMS メッセージ駆動型 EJB で問題が発生しました。メッセージ処理内で、一部のマスタ データ フィールドをチェックする必要があります。パフォーマンスを向上させるために、このマスター データは@Singleton @StartupEJB を使用してキャッシュ構造にプリロードされます。データのロードには約 30 秒かかります。

私の問題は、キャッシュが完全に初期化されていない場合でもキュー メッセージの処理が開始され、メッセージ検証エラーが発生することです。

MDB とスタートアップ EJB の間の依存関係を定義しようとしましたが、理解した限りでは、@DependsOnアノテーションは@SingletonEJB でのみ機能します。したがって、私のソリューションが機能しないことは明らかです;-)

起動 Bean コード:

@Singleton
@Startup
public class StartupBean {

    @PostConstruct
    void atStartup() {
        // TODO load master data cache (takes about 30 seconds)
    }

    @PreDestroy()
    void atShutdown() {
        // TODO free master data cache
    }
}

注: 読みやすくするために、例から実際のコードを削除しました :-)

メッセージ駆動型 Bean コード:

@MessageDriven(name="SampleMessagingBean", activationConfig = {
        @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
        @ActivationConfigProperty(propertyName="destination", propertyValue="jms/SampleQueue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
    })
    @DependsOn("StartupBean")
    public class SampleMessagingBean implements MessageListener {

    public void onMessage(Message message) {
        // TODO validate message using master data cache
    }
}

質問:スタートアップ Bean がキャッシュのロードを完了するまでメッセージ処理を一時停止するにはどうすればよいですか?

どんな提案でも大歓迎です:-)!

4

1 に答える 1

4

最初に、mdb にシングルトン EJB を注入するだけでメッセージの消費を遅らせることができると考えましたが、いいえ、Singleton-ejb の @PostConstruct が完了する前にメッセージの消費を開始する場合がありました。そのため、メソッド呼び出しも追加し、機能し始めました

これはglassfishで機能しましたが、jbossで機能しない理由がわかりません

シングルトン EJB:

@Singleton
@Startup
public class SingletonBean {
    private Logger logger = Logger.getLogger(getClass().getName());

    private boolean init = false;

    public boolean isInit() {
        return init;
    }

    @PostConstruct
    public void init() {
        logger.error("singleton init start");

        //Do something that takes time here

        init = true;
        logger.error("singleton init end ");
    }
}    

およびmdb:

@MessageDriven(...)
public class SomeMdb implements MessageListener {
    private Logger logger = Logger.getLogger(getClass().getName());

    @EJB
    SingletonBean sb;

    @PostConstruct
    public void init() {
        logger.error("mdb init start");
        if (!sb.isInit()) {
            logger.error("never happens");
        }
        logger.error("mdb init complete");
    }

    public void onMessage(Message message) {
        logger.error("onMessage start");
    }
}    

mdb が init を完了する前に、SingletonBean が init を完了するのを常に待機するようになりました (ログに表示されます)。

19:51:51,980 [ad-pool-1; w: 3] ERROR SomeMdb       - mdb init start
19:51:52,122 [ad-pool-4848(4)] ERROR SingletonBean - singleton init start
19:51:56,316 [ad-pool-4848(4)] ERROR SingletonBean - singleton init end 
19:51:56,317 [ad-pool-1; w: 3] ERROR SomeMdb       - mdb init complete
19:51:56,317 [ad-pool-1; w: 3] ERROR SomeMdb       - onMessage start
于 2012-10-30T16:35:58.980 に答える