如何在基于servlet的Web应用程序中运行后台任务?

问题描述 投票:84回答:5

我正在使用Java,我希望在我的应用程序中保持servlet不断运行,但我不知道怎么做。我的servlet有一个方法,它每天从数据库中提供用户的计数以及整个数据库中用户的总数。所以我想保持servlet不断运行。

multithreading java-ee servlets background-process scheduledexecutorservice
5个回答
191
投票

你的问题是你误解了qazxsw poi的目的。它旨在对HTTP请求采取行动,仅此而已。您只需要一个每天运行一次的后台任务。

EJB available? Use servlet

如果您的环境恰好支持EJB(例如WildFly,JBoss AS / EAP,TomEE,GlassFish等),那么请改用@Schedule

@Schedule

是的,这就是全部。容器将自动拾取和管理它。

EJB unavailable? Use @Singleton public class BackgroundJobManager { @Schedule(hour="0", minute="0", second="0", persistent=false) public void someDailyJob() { // Do your job here which should run every start of day. } @Schedule(hour="*/1", minute="0", second="0", persistent=false) public void someHourlyJob() { // Do your job here which should run every hour of day. } @Schedule(hour="*", minute="*/15", second="0", persistent=false) public void someQuarterlyJob() { // Do your job here which should run every 15 minute of hour. } }

如果您的环境不支持EJB(即不是真正的Java EE服务器,例如Tomcat,Jetty等),请使用ScheduledExecutorService。这可以由ScheduledExecutorService发起。这是一个启动示例:

ServletContextListener

工作类看起来像这样:

@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}
public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

}

Do not ever think about using public class SomeQuarterlyJob implements Runnable { @Override public void run() { // Do your quarterly job here. } } /java.util.Timer in Java EE

永远不要在Java EE中直接使用java.lang.Thread和/或java.util.Timer。这是麻烦的秘诀。在这个与JSF相关的答案中可以找到一个详细的解释:java.lang.Thread


4
投票

我建议使用像石英这样的库,以便定期运行任务。 servlet真正做了什么?它会向您发送报告?



2
投票

实现两个类并在http://www.sauronsoftware.it/projects/cron4j/manual.php中调用startTask()

main

0
投票

在可能有多个非jee容器运行的生产系统中。使用像Quartz调度程序这样的企业调度程序,可以将其配置为使用数据库进行任务maamgememt。

© www.soinside.com 2019 - 2024. All rights reserved.