我正在使用Java,但我想保持servlet在我的应用程序中连续运行,但是我没有得到如何做的信息。我的servlet有一种方法,可以每天提供数据库中用户的数量以及整个数据库中用户的总数。因此,我想为此继续保持servlet的运行。

评论

“连续运行”是什么意思?

连续运行是什么意思?只要您的应用服务器运行,它就会一直运行

我不明白为什么它必须连续运行...如果有人想要“用户数”,那么他们会调用您的servlet方法,然后您将其提供给他们?

@trojanfoe实际上我想要每天的用户数,因此我将不得不每天手动运行servlet,而不是那样我想要连续运行servlet。所以我不需要每天运行servlet。
@pritsag:那里有一个servlet来满足用户请求,而不是运行批处理作业。

#1 楼

您的问题是您误解了Servlet的目的。它旨在对HTTP请求执行操作,仅此而已。您只需要每天执行一次的后台任务。

EJB是否可用?如果您的环境碰巧支持EJB(例如WildFly,JBoss,TomEE,Payara,GlassFish等真正的Java EE服务器),请使用@Schedule。以下是一些示例:

@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.
    }

    @Schedule(hour="*", minute="*", second="*/5", persistent=false)
    public void someFiveSecondelyJob() {
        // Do your job here which should run every 5 seconds.
    }

} 


是的,仅此而已。容器将自动进行拾取和管理。

EJB不可用?使用@Schedule如果您的环境不支持EJB(即您未使用的不是真正的Java EE服务器,而是使用了诸如Tomcat,Jetty等准系统的servlet容器),那么使用ScheduledExecutorService。这可以通过ScheduledExecutorService启动。这是一个启动示例:

@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);
        scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
    }

    @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.
    }

}




public class SomeQuarterlyJob implements Runnable {

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

}




public class SomeFiveSecondelyJob implements Runnable {

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

}

曾经考虑过在基于Java EE / Servlet的环境中使用ServletContextListener / java.util.Timer

最后但并非最不重要的是,永远不要在Java EE中直接使用java.lang.Thread和/或java.util.Timer。这是麻烦的秘诀。在与JSF有关的同一问题上可以找到详细的解释:使用计时器在JSF托管Bean中生成线程以执行计划的任务。

评论


@BalucS谢谢您,先生,您的解决方案对我有所帮助,我了解了ScheduledExecutorService,这对我来说是Java的新手。再次感谢您。

–pritsag
2011年1月15日7:36

@BalusC:将类UpdateCounts放在web.xml中的什么位置?

–阿什温
2012年6月13日9:38

@Ashwin web.xml是一个部署描述符。类UpdateCount与部署无关,因此不必将其放在web.xml中

–informatik01
13年8月12日在0:15

ScheduledExecutorService的一个关键问题:确保在执行程序中捕获所有异常。如果您的run方法逃脱了异常,则执行程序将静默停止执行。这是一个功能,而不是错误。阅读文档并进行一些谷歌搜索。

–罗勒·布尔克
14-10-18在17:50



@Agi:如果未按照示例正确调用scheduler.shutdownNow(),则会发生这种情况。如果未调用此函数,则调度线程确实将继续运行。

– BalusC
18年6月26日在15:12



#2 楼

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

评论


是的,它为我提供了每天创建的用户数以及数据库中的总用户数。

–pritsag
2011年1月14日13:09

hu?您能否描述系统的完整架构。我迷路了。

–扭曲者
2011年1月14日13:17

@Twister我是Java的新手,处于学习阶段,先生,对servlet的了解并不多。

–pritsag
2011年1月14日13:21



问题不在于servlet。您正在谈论什么应用程序? (ps:删除您的评论,尤其是我回答的评论是一个坏主意)

–扭曲者
2011年1月14日13:22



@twister,当用户点击该应用程序时,他将获得所有详细信息,例如今天创建了多少用户,到现在为止有多少用户被激怒等等。我想连续在后台运行servlet,以便用户可以获取更新我不知道这是不正确的解释。(ps:我知道这是个坏主意,抱歉。)

–pritsag
2011年1月14日13:26



#3 楼

实现两个类并在startTask()中调用main

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


评论


这绝对不是在Web应用程序中执行此操作的方法-而是查看@BalusC的上述答案-他在这里是正确的,我想您可以相信他的所有答案。

–吉屋
18年5月21日在13:46



#4 楼

您可以使用cron4j。 http://www.sauronsoftware.it/projects/cron4j/manual.php

#5 楼

在可能有多个运行的非Jee容器的生产系统中。使用非企业调度程序(例如Quartz调度程序),可以将其配置为将数据库用于任务管理。