구글 코드 및 GitHub 등 Solr Data Import 관련된 오픈 소스들이 많다 . 물론 Quartz를 이용한 스케줄러에 대한 것도 많이 존재한다 . 지금 정리하는 내용은 GitHub에 존재하는 사이트를 기준으로 했고, 이 사이트는 Google Code 의 소스를 기반으로 해서 확장(?)한 것으로 보인다. 사용한 코드도 소스를 적용할 환경과 요구에 맞도록 변경해서 사용한 것이기 때문에 실제 사이트에서 제시하고 있는 내용과는 다를 수 있다. 물론 설정 방법은 동일하게 사용한다.
Scheduler 관련 사이트들
스케줄러 기능을 사용하기 위해서는 다음과 같은 구성요소가 필요하다.
Scheduler 설치와 구성
설치와 구성은 다음과 같이 설정하면 된다.
DataImportScheduler-0.0.1.jar 파일을 Solr 설치 서버 (주로 톰캣)의 클래스패스 (별다른 설정이 없다면 WEB-INF/lib) 에 복사한다. 구동에 필요한 배포 대상 Jar 들은 아래와 같다.
- Quartz-2.2.1.jar
- Quartz-jobs-2.2.1.jar
- Fluent-hc-4.3.2.jar
- jta-1.1.jar
당연한 것이지만, Solr, Lucene, Http, slf4j 등의 관련 Jar 들은 이미 구성된 Solr 서버에 존재하므로 빠진 부분만 추가로 배포하면 된다.
웹 설정 (별다른 설정이 없다면 WEB-INF/web.xml) 에 다음과 같이 리스너를 설정한다. Solr 서버의 ServletContextListener를 상속하여 Context 가 초기화 및 제거 될 때 Quartz Scheduler를 On/Off 처리하기 위한 연결고리로 사용한다.
...
...
|
DataImportScheduler 는 기본적으로 SolrResourceLoader 를 사용하여 경로를 판단하게 된다. (물론 소스에서 이를 수정해서 다른 폴더로 사용할 수도 있다) 기본적으로는 Solr 가 구동될 때 옵션으로 지정했던 solr.solr.home 에 지정한 Solr Home 경로를 기준으로 한다. (ex. -Dsolr.solr.home=Solr홈경로) 이 폴더를 기준으로 "conf" 폴더를 찾게 되므로 (ex. Solr.solr.home=C:\Solr 라고 지정했으면 파일을 찾는 경로는 C:\Solr\conf 가 된다) 이 폴더에 quartz.properties 파일을 생성한다. 이 파일은 Quartz 구동과 관련된 설정 정보를 위한 것으로 전체 Core 에 대해서 동작하게 된다. 템플릿은 다운로드 한 jar 파일 내의 templates 폴더 밑의 파일을 참조하면 된다. 없다면 Quartz 의 기본 설정 정보 를 참고하도록 한다. 일반적으로 사용할 경우는 이 설정을 변경할 이유가 없다. 아래는 기본 사용할 정보를 설정한 파일의 내용이다.
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: SolrDataImportScheduler
org.quartz.scheduler.instanceId: AUTO
org.quartz.scheduler.skipUpdateCheck: true
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 3
org.quartz.threadPool.threadPriority: 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#============================================================================
# Configure Plugins
#============================================================================
#org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin
org.quartz.plugin.jobInitializer.class: com.msfl.tools.solr.quartz.plugins.xml.SolrXMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames: quartz_schedule.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound: true
org.quartz.plugin.jobInitializer.scanInterval: 120
org.quartz.plugin.jobInitializer.wrapInUserTransaction: false
|
Solr home/conf 폴더에 (위와 동일 경로) 에 quartz_schedule.xml 파일을 생성한다. (위의 quartz.properties에 설정한 fileNames 값과 동일한 파일) 이 파일은 Quartz 에 의해서 수행되어야 할 Jobs 와 실행 Triggering 에 대한 정보를 위한 것으로 템플릿은 다운로드 한 jar 파일 내의 templates 폴더 밑의 파일을 참조하면 된다. 없다면 Jobs 에 대한 설정 정보 를 참고하도록 한다. 일반적으로 Full / Delta, 일회 / 주기적 호출 등의 정보를 상황에 맞도록 설정한다.
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData
version="1.8">
|
Cron 표현식
Java에서 스케줄을 처리할 때 많이 사용하는 것이 Quartz 이고 여기서 제공하는 Trigger는 SimpleTrigger 와 CronTrigger 가 있다.
- SimpleTrigger - 단순히 Interval, Delay, Repeat Times 등의 설정을 통해서 구동된다.
- CronTrigger - Linux 의 cron 표현식을 사용한 설정을 통해서 구동된다.
필드 설명
cron표현식은 ' ' 으로 구분되는 6 ~ 7 개의 문자 (숫자, 영숫자, 기호) 를 사용하여 지정한다 . 아래의 표는 사용할 수 있는 필드를 정리한 것이다.
필드
|
필수
|
허용 값
|
특수 설정 문자
|
초 (seconds)
|
YES
|
0 ~ 59
|
, - * /
|
분 (minutes)
|
YES
|
0 ~ 59
|
, - * /
|
시 (hours)
|
YES
|
0 ~ 23
|
, - * /
|
날짜 (day of month)
|
YES
|
1 ~ 31
|
, - * / ? L W
|
월 (month)
|
YES
|
1 ~ 12 또는 JAN ~ DEC
|
, - * /
|
요일 (day of week)
|
YES
|
1 ~ 7 또는 SUN ~ SAT
|
, - * / ? L #
|
년 (year)
|
NO
|
'' 또는 1979 ~ 2099
|
, - * /
|
특수 설정 문자
- , : 여러 값을 의미하며, 시간에 14, 18 로 지정했다면 24시간 기준으로 오후 2시와 오후 6시가 된다.
- * :모든 값을 의미하며, 초에 사용하면 매초, 분에 사용하면 매분이 된다.
- ? : 값을 정하지 않는 것으로 일과 요일에 사용 가능하며, 일에 사용하면 어떤 요일도 상관없다는 뜻이 된다.
- - :범위를 의미하는 것으로 0 - 10 이면 0 부터 10까지를 의미한다 . 마지막 값인 10도 포함된다는 점을 주의해야 한다.
- / : 증분을 의미하는 것으로 분에 0 / 5 로 지정하면 0분 부터 매 5분마다를 의미한다. 즉, 0, 5, 10, 15, 20, … 을 의미한다.
- L : 마지막 값을 의미하는 것으로 날짜에 사용하면 해당 월의 마지막 일자를 의미한다. 30 또는 31 이며 2월은 28일 (윤달은 29일)이 된다.
- W : 주중 평일 (Weekday, MON, TUE, WED, THU, FRI) 을 의미하는 것으로 날짜와 같이 쓰면 그 날짜가 주중인 날을 의미한다.
- # : n 번째를 의미하는 것으로 예를 들어 특정 달의 몇 번째 요일을 지정하는 경우에 사용한다. 즉, 3번째 월요일은 2#3 이다. 2 는 SUN 부터 시작하므로 MON을 의미하고, 3 은 3번째를 의미한다. MON#3 으로 표현해도 된다.
사용 예
표현식
|
의미
|
0 0 12 * * ?
|
매일 12시 (정오) 에 동작
|
0 15 10 ? * *
|
매일 오전 10시 15분 에 동작
|
0 15 10 * * ?
|
매일 오전 10시 15분 에 동작
|
0 15 10 * * ? *
|
매일 오전 10시 15분 에 동작
|
0 15 10 * * ? 2005
|
2005년 매일 아침 10시 15분에 동작
|
0 * 14 * * ?
|
매일 오후 2시 부터 2시 59분까지 매 분마다 동작
|
0 0/5 14 * * ?
|
매일 오후 2시부터 2시 55분까지 매 5분마다 동작
|
0 0/5 14,18 * * ?
|
매일 오후 2시 부터 2시 55분까지 매 5분마다, 오후 6시 부터 6시 55분까지 매 5분마다 동작
|
0 0-5 14 * * ?
|
매일 오후 2시부터 5분까지 매분 에 동작
|
0 10,44 14 ? 3 WED
|
매년 3월의 수요일마다 오후 2시 10분과 44분 에 동작
|
0 15 10 ? * MON-FRI
|
월요일부터 금요일까지 오전 10시 15분 에 동작
|
0 15 10 15 * ?
|
매달 15일 오전 10시 15분 에 동작
|
0 15 10 L * ?
|
매달 마지막 날 오전 10시 15분 에 동작
|
0 15 10 ? * 6L
|
매달 마지막 금요일 오전 10시 15분 에 동작
|
0 15 10 ? * 6L 2002~2005
|
2002년부터 2005년까지 매달 마지막 금요일 오전 10시 15분 에 동작
|
0 15 10 ? * 6#3
|
매달 3번째 금요일 오전 10시 15분 에 동작
|
0 0 12 1/5 * ?
|
매달 첫날부터 5일마다 12시(정오) 에 동작
|
0 11 11 11 11 ?
|
매년 11월 11일 오전 11시 11분 0초 에 동작
|
주의할 점
- 날짜와 요일에 ? 를 지정하면 서로 배타적으로 동작한다. 즉, 날짜에 ? 를 사용하면 요일에 사용할 수 없고, 요일에 사용하면 날짜에 사용할 수 없다는 것이다. 매달 x일이 y요일인 경우가 발생할 수 없기 때문이다.
- 범위(-)를 사용할 때는 항상 마지막 값이 포함된다. 특정 시간을 제외할 경우는 범위를 분리해서 사용해야 한다. 예를 들어 6시를 제외한 모든 시간이라면 0-5,7-23 으로 표현해야 한다. 0-6으로 하면 6이 포함된다.
- 날짜에 L 과 W를 함께 사용하면 매월 마지막 평일의 의미가 된다.
- 요일에 x#5를 사용하면 5번째 주의 x요일을 의미한다.
- 해외에서는 썸머타임 (daylight saving) 을 고려해야 한다. 자정부터 새벽 1시까지의 시간은 썸머타임 시행 시에는 건너 뛰거나 반복해서 실행될 가능성이 있다.
결론
위와 같이 설정을 한 후에 Solr 를 구동하면 Log 상에 Quartz 와 관련된 Scheduler 가 동작하는 내용을 확인할 수 있다. 그러고 quartz_shedule.xml 의 job 과 trigger 가 제대로 설정된 상태라면 해당 Trigger 조건에 맞게 DataImport 가 호출되는 것을 확인할 수 있다. 만일 제대로 설정한 상태지만 Trigger 가 구동되지 않는다면 주로 cron trigger 일 경우에는 cron-expression 이 제대로 설정되지 않았을 경우가 많다. Cron-expression 은 Cron Marker 사이트 를 통해서 생성할 수 있다.
댓글
댓글 쓰기