2013-06-30 61 views
4

我的web應用程序中有一個石英作業,它由一個servlet啓動。 當我重新部署我的應用程序獲得以下消息Java石英內存泄漏消息

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

而且在生產,我們有Tomcat的服務器不./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); 

正如你可以看到我的工作開始,每天一次。我沒有看到可以檢查國旗的點,取消這項工作。

+0

我認爲應該在[serverfault](http://serverfault.com/)(如果它是專業系統)或[超級用戶](http://superuser.com)上詢問這個問題。只是一個提示,如果你在這裏沒有得到任何答案。 – Qben

回答

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 

石英-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> 

,並使用QuartzInitializerServlet在我的web.xml

<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. 
+0

沒問題,如果你的工作時間表,工作時間和關機時間不衝突。你的工作運行多久了?而且,如果系統關閉並且作業仍在運行(更長時間),會發生什麼情況? – Beryllium

3

如果正在關機,您的工作必須定期檢查(例如,在每次迭代中)。 您需要在工作中正確實施這一點。 Quartz和Tomcat都不能在這裏幫忙(他們應該如何阻止一個線程?)。

您可以在ServletContextListener,方法contextDestroyed中設置標誌。 如果標記已設置,則作業必須儘快完成。

石英線程在您的Web應用程序的一生中保存下來!因此,您的Web應用程序的更新並不能保證作業被終止。在一次新的部署之後,我的殭屍工作「突然」醒來。這是少數你不相信你的日誌文件的情況之一。

這就是爲什麼您必須爲kill Tomcat,因爲有運行的線程尚未由Tomcat創建。

+0

所以我添加了一些源代碼來描述我的問題。 – Tim

+0

調用很好。有趣的軟件是* job *本身。在工作中,您應該檢查「正在關機」標誌,然後作業應該終止。沒有安全的方式來終止*外部世界*的工作。 – Beryllium