简体   繁体   English

关闭应用程序服务器时优雅地停止 @Schedule EJB

[英]Stop @Schedule EJB gracefully when shutting down application server

I have a stateless EJB with a method that should executed periodically.我有一个无状态的 EJB,它的方法应该定期执行。 This works well so far.到目前为止,这运作良好。 However, I want the stop the method gracefully when it is running while shutting down application server.但是,我希望在关闭应用程序服务器时优雅地停止该方法。 Therefore, I have implemented a stop() method annotated with @PreDestroy .因此,我实现了一个用@PreDestroy注释的stop()方法。

However, the stop() method does not work as expected.但是, stop()方法无法按预期工作。 When stopping my application server while schedule() is running, the application server waits until schedule() terminates and calls stop() only afterwards.schedule()运行时停止我的应用程序服务器时,应用程序服务器会等到schedule()终止,然后才调用stop()

@Stateless
public class TestService {

    private static final Logger logger = Logger.getLogger(TestService.class);

    private volatile boolean shutdown = false;

    @Schedule(hour = "*", minute = "*", second = "*/15", persistent = false)
    public void schedule() throws InterruptedException {
        logger.info("Start execution");
        for (int i = 0; !shutdown && i < 10; ++i) {
            logger.info("Step " + i);
            Thread.sleep(1000);
        }
        logger.info("Stopped execution");
    }

    @PreDestroy
    public void stop() {
        logger.info("Trigger stop");
        shutdown = false;
    }

}

Here, I have posted only a minimal example EJB for reproducing my issue.在这里,我只发布了一个用于重现我的问题的最小示例 EJB。 In my real EJB, it is even worse.在我真正的 EJB 中,情况更糟。 When executing any transaction after triggering the server shutdown, the application server (JBoss EAP 7.1 with WildFly 11) throws a ComponentIsStoppedException .在触发服务器关闭后执行任何事务时,应用程序服务器(带有 WildFly 11 的 JBoss EAP 7.1)抛出ComponentIsStoppedException So, I have no chance to gracefully shutdown my EJB.所以,我没有机会优雅地关闭我的 EJB。

An alternative solution could be to use the EJB TimerService ?另一种解决方案是使用 EJB TimerService吗?

Something like this:像这样的东西:

@Startup
public class TestService {

    @Resource
    private TimerService ejbTimerService;

    private Timer timer = null;

    @PostConstruct
    public void setup() {
        ScheduleExpression schedule = new ScheduleExpression().hour("*").minute("*").second("15");
        timer = ejbTimerService.createCalendarTimer(schedule);
        System.out.println("Timer " + timer.toString() + " created");
    }

    @Timeout
    public void onTimeout(Timer timer) {
        System.out.println("Timer schedule: " + timer.getSchedule());
    }

    @PreDestroy
    public void tearDown() {
        logger.info("Trigger stop");        
    }

    // Method to call when stopping application server
    public void smoothShutdown() {
       if (timer!=null) timer.cancel();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM