4

我的网络应用程序中有一个石英工作,它是由一个 servlet 启动的。当我重新部署我的应用程序时,我收到以下消息

[DefaultQuartzScheduler_Worker-5] but has failed to stop it. This is very likely to create a memory leak

同样在生产中,我们遇到了tomcat-server在./shutdown.sh之后没有停止的问题,因此我们必须终止该进程。在我看来,它依赖于石英工作,这不能停止。

如何通过重新部署我的应用程序或关闭服务器来停止石英作业?

我使用tomcat 7,石英2.1.6 ...

    SchedulerFactory sf = new StdSchedulerFactory();

    Scheduler scheduler = sf.getScheduler();

    scheduler.start();

    JobDetail job = JobBuilder.newJob(XYZJob.class).withIdentity("job1", "group1").build();

    Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1")
                                                 .startNow()
                                                 .withSchedule(CronScheduleBuilder.cronSchedule("0 0 1 * * ?"))
                                                 .build();

    scheduler.scheduleJob(job, trigger);

如您所见,我的工作每天开始一次。我看不到可以检查标志以取消工作的点。

4

2 回答 2

4

我的解决方案是更改我的配置。我创建了一个quartz.properties

org.quartz.scheduler.instanceName = XYZJob
org.quartz.threadPool.threadCount = 1
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
org.quartz.plugin.jobInitializer.class =org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin 
org.quartz.plugin.jobInitializer.fileNames = quartz-config.xml 
org.quartz.plugin.jobInitializer.failOnFileNotFound = true

一个quartz-config.xml

<?xml version="1.0" encoding="UTF-8"?>

<job-scheduling-data
xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData 
http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
version="1.8">

<schedule>
    <job>
        <name>XYZJob</name>
        <group>XYZGroup</group>
        <description>Check the contracts idle period</description>
        <job-class>com.test.job.cron.XYZJob</job-class>
    </job>

    <trigger>
        <cron>
            <name>CronTriggerName</name>
            <job-name>XYZJob</job-name>
            <job-group>XYZGroup</job-group>
            <!-- It will run every day at 1 am -->
            <cron-expression>0 0 1 * * ?</cron-expression>
        </cron>
    </trigger>
</schedule>

并在我的 web.xml 中使用 QuartzInitializerServlet

<servlet>
     <servlet-name>QuartzInitializer</servlet-name>
     <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
     <init-param>
         <param-name>config-file</param-name>
         <param-value>quartz.properties</param-value>
     </init-param>
     <init-param>
         <param-name>shutdown-on-unload</param-name>
         <param-value>true</param-value>
     </init-param>
     <init-param>
         <param-name>start-scheduler-on-load</param-name>
         <param-value>true</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
 </servlet>

关闭我的Tomcat后,我收到以下消息

INFO: QuartzInitializer: Quartz Scheduler successful shutdown.
于 2013-07-02T13:08:44.167 回答
3

如果正在进行关闭,您的作业必须定期检查(例如,在每次迭代中)。在您的工作中正确实施这一点取决于您。Quartz 和 Tomcat 都不能在这里提供帮助(他们应该如何停止线程?)。

ServletContextListener您可以在, 方法中设置一个标志contextDestroyed。如果设置了标志,则作业必须尽快完成。

Quartz 线程否则会在您的 Web 应用程序的生命周期中存活下来!因此,您的 Web 应用程序的更新并不能保证作业会终止。在新部署之后,我的僵尸工作“突然”醒来。这是您不相信您的日志文件的少数情况之一。

这就是你必须使用killTomcat 的原因,因为有运行的线程不是由 Tomcat 创建的。

于 2013-06-30T20:48:23.473 回答