Tomcat Shutdown 시 Quartz Scheduler Shutdown
Quatz 를 이용하여 스케줄러를 사용 할 때 Tomcat 를 stop 시키면
해당 스케줄러가 자동으로 Destory 되지 않는다. 때문에 다시 Tomcat 을 start 시키면
scheduler 가 중복되서 돌아가게 된다.
이런 문제를 해결하기 위해서 아래와 같은 방법을 이용 한다.
1. Tomcat Start 시 root context 로 bean 등록
<bean id="setPostProcessor" class="webreport.pnp.common.beans.PostProcessor" autowire="byType"/> |
2. 해당 bean 은 BeanPostProcessor, BeanFactoryPostProcessor 를 implements
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { SchedulerCronTrigger.getInstance(); // scheduer start } |
3. SchedulerCronTrigger 는 singleton 으로 구성
public class SchedulerCronTrigger { private static Logger logger = Logger.getLogger(SchedulerCronTrigger.class); private static volatile SchedulerCronTrigger INSTANCE; private SchedulerFactory schedFact = null; private Scheduler sched = null;
private SchedulerCronTrigger() {}
public static SchedulerCronTrigger getInstance(){ if( INSTANCE == null ){ synchronized (SchedulerCronTrigger.class) { if( INSTANCE == null){ INSTANCE = new SchedulerCronTrigger(); INSTANCE.initInstance(); } } } return INSTANCE; }
private void initInstance(){ try { if(null == schedFact){ logger.info("스케줄 생성"); // 스케쥴 생성후 시작 schedFact = new StdSchedulerFactory(); sched = schedFact.getScheduler();
if(false == sched.isStarted()){ logger.info("스케줄 Start"); sched.start();
// 보고서 생성 scheduler JobDetail makeReport = new JobDetail("job1", "makeReport", SchedulerMakeReport.class); CronTrigger trigger1 = new CronTrigger("trigger1", "makeReport", "0 0 3 * * ?"); // default 03:00 sched.scheduleJob(makeReport, trigger1); } } } catch (Exception e) { e.printStackTrace(); } }
// public void updateCronMakeReport(String cronStr){ try{ sched.deleteJob("job1", "makeReport"); JobDetail job1 = new JobDetail("job1", "makeReport", SchedulerMakeReport.class); CronTrigger trigger1 = new CronTrigger("trigger1", "makeReport", cronStr); sched.scheduleJob(job1, trigger1); }catch(Exception e){ e.printStackTrace(); } } } |
4. web.xml 에 Scheduler shutdown 시키는 리스너 등록
<listener> <listener-class>webreport.pnp.common.util.ShutDownHook</listener-class> </listener> |
5. ShutdownScheduler 는 ServletContextListener implements
public class ShutDownHook implements ServletContextListener{ @Override public void contextDestroyed(ServletContextEvent ev) { try{ if(ev != null && ev.getServletContext() != null){ Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.shutdown(true); Thread.sleep(1000); // sleep for a bit so that we don't get any errors } }catch(Exception e){ e.printStackTrace(); } }
@Override public void contextInitialized(ServletContextEvent arg0) {} } |