java quartz 라이브러리의 job 실행지연 현상 해결방법에 대하여 문의합니다.


java quartz 라이브러리를 이용하여 등록된 스케줄에 대하여 일주일 단위로 스케줄 실행이 지연되는 현상이 발생합니다.

눈에 띄는 에러메시지는 발생하지 않으며 특정 스케줄에 대해서 로그상으로 지연되는 현상을 확인할 수 있으며, 지연되었던 스케줄에 대하여 실행되어야할 api가 실패하는 결과가 일주일 단위로 반복되고 있습니다.

소스상으로는 synchronized(){} 처리된 부분이 실제 실행되어야할 api입니다.

구조적인 문제해결 혹은 개선방안에 대하여 도움을 얻고자 합니다.

감사합니다.

로그

[2016-04-11 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-11 08:55:15] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)

[2016-04-12 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-12 07:19:10] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)
[2016-04-13 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-13 07:17:11] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)
[2016-04-14 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-14 07:17:25] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)
[2016-04-15 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-15 07:18:33] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)
[2016-04-16 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-16 07:19:09] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)
[2016-04-17 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-17 07:19:16] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)

[2016-04-18 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-18 08:48:25] INFO  [JobWorker.java:52] IT_Daily_ilji ended...(Period)

문제가 되는 소스

public void execute(JobExecutionContext context)throws JobExecutionException{

        JobDataMap dataMap = context.getJobDetail().getJobDataMap();

        String reportFile = dataMap.getString("ReportFile");
        String reportName = dataMap.getString("ReportName");
        String groupName = dataMap.getString("GroupName");
        String reportSys = dataMap.getString("REPORT_SYS");


        logger.info(reportName + " started...(Period)");

        synchronized(JobWorker.class){  
            Creater creater = new Creater(reportName, reportSys);
            //creater.setLogger(logger);
            if(reportSys.equals("RD"))
                creater.rdrun();
            else
                creater.run();
        }

        logger.info(reportName + " ended...(Period)");
    }

quartz version

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.1
Created-By: 1.3.1_07-b02 (Sun Microsystems Inc.)
Built-By: jhouse
Main-Class: org.quartz.helpers.VersionPrinter
Sealed: false

Name: quartz
Implementation-Title: Quartz
Implementation-Version: 1.4.5 March 13 2005
Implementation-Vendor: The Quartz project developers.
Implementation-Vendor-URL: http://www.quartzscheduler.org
Specification-Title: Quartz
Specification-Version: 1.4
Specification-Vendor: The Quartz project developers.
Specification-Vendor-URL: http://www.quartzscheduler.org
Sealed: false

로그 내용 추가

날짜는 다르지만, 그 전 주 월요일에 해당하는 로그입니다.

[2016-04-04 07:05:00] INFO  [JobWorker.java:39] IT_Daily_ilji started...(Period)
[2016-04-04 08:40:55] INFO  [Creater.java:125] [IT_Daily_ilji]Report Create start...(Period)
[2016-04-04 08:40:55] INFO  [Creater.java:587] [IT_Daily_ilji]Check gc.getTime :Sun Apr 03 08:40:55 KST 2016
[2016-04-04 08:40:55] INFO  [Creater.java:396] [IT_Daily_ilji]rptEndTime  : 20160403  rptStartTime : 20160403 Date ds : null rptFormat : pdf^xls^html^rtf^
[2016-04-04 08:40:55] INFO  [JasperRunner.java:114] [IT_Daily_ilji]JVM cmd : ...............................................
[2016-04-04 08:40:56] INFO  [JasperRunner.java:121] [IT_Daily_ilji]< PeriodicExporterJVM ... START >
  • 2016년 06월 01일에 수정됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.
  • 2016년 05월 26일에 작성됨

  • creater의 run 혹은 rdrun 로직내에서 수행이 오래 걸릴가능성은 없나요?    허대영(Daeyoung Heo)   2016.5.26 16:49     
  • @허대영 질문란에 내용추가하였습니다. 실제 Creater 진입자체가 상당히 늦습니다.    Jo Seongwon   2016.5.26 17:20     
조회수 187


1 답변


synchronized(JobWorker.class) 부분의 문제인것 같네요.

해당 부분을 Critical Section으로 만드는 것이 목표이면 concurrent 패키지로 바꿔서 테스트 해보세요.

// 클래스 멥버에 java.util.concurrent.locks.ReentrantLock를 선언하고,
static ReentrantLock critical = new ReentrantLock(); 

public void execute(JobExecutionContext context)throws JobExecutionException{

    // ... 생략
    // Critical Section
    critical.lock();
    // 한번에 하나의 스레드만 통과.
    // 이미 수행중일 경우, 종료하고자 하는 경우 tryLock()을 참고하세요.
    try {
            Creater creater = new Creater(reportName, reportSys);
            //creater.setLogger(logger);
            if(reportSys.equals("RD"))
                creater.rdrun();
            else
                creater.run();        
    } finally
        critical.unlock();
    }

}
  • 2016년 06월 13일에 작성됨
    리눅스(유닉스) 기반의 시스템에서 웹 서비스를 개발하고 있습니다.

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close