Spring Boot 2.X Quartz 클러스터링 스케줄러


목차

1. Quartz

  • 1.1. Quartz란

  • 1.2. 동작방식

2. Sample

  • 2.1. Quartz-Controller

3. Trouble Shooting

Quartz

SampleCode

####

-- DROP TABLE IF EXISTS T_QRTZ_FIRED_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_PAUSED_TRIGGER_GRPS;
-- DROP TABLE IF EXISTS T_QRTZ_SCHEDULER_STATE;
-- DROP TABLE IF EXISTS T_QRTZ_LOCKS;
-- DROP TABLE IF EXISTS T_QRTZ_SIMPLE_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_SIMPROP_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_BLOB_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_CRON_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_TRIGGERS;
-- DROP TABLE IF EXISTS T_QRTZ_CALENDARS;
-- DROP TABLE IF EXISTS T_QRTZ_JOB_DETAILS;


CREATE TABLE T_QRTZ_JOB_DETAILS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    JOB_CLASS_NAME   VARCHAR(250) NOT NULL,
    IS_DURABLE VARCHAR(1) NOT NULL,
    IS_NONCONCURRENT VARCHAR(1) NOT NULL,
    IS_UPDATE_DATA VARCHAR(1) NOT NULL,
    REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE T_QRTZ_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    JOB_NAME  VARCHAR(200) NOT NULL,
    JOB_GROUP VARCHAR(200) NOT NULL,
    DESCRIPTION VARCHAR(250) NULL,
    NEXT_FIRE_TIME BIGINT(13) NULL,
    PREV_FIRE_TIME BIGINT(13) NULL,
    PRIORITY INTEGER NULL,
    TRIGGER_STATE VARCHAR(16) NOT NULL,
    TRIGGER_TYPE VARCHAR(8) NOT NULL,
    START_TIME BIGINT(13) NOT NULL,
    END_TIME BIGINT(13) NULL,
    CALENDAR_NAME VARCHAR(200) NULL,
    MISFIRE_INSTR SMALLINT(2) NULL,
    JOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
        REFERENCES T_QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
);

CREATE TABLE T_QRTZ_SIMPLE_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    REPEAT_COUNT BIGINT(7) NOT NULL,
    REPEAT_INTERVAL BIGINT(12) NOT NULL,
    TIMES_TRIGGERED BIGINT(10) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES T_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE T_QRTZ_CRON_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    CRON_EXPRESSION VARCHAR(200) NOT NULL,
    TIME_ZONE_ID VARCHAR(80),
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES T_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE T_QRTZ_SIMPROP_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 VARCHAR(1) NULL,
    BOOL_PROP_2 VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES T_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE T_QRTZ_BLOB_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    BLOB_DATA BLOB NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
        REFERENCES T_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
);

CREATE TABLE T_QRTZ_CALENDARS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    CALENDAR_NAME  VARCHAR(200) NOT NULL,
    CALENDAR BLOB NOT NULL,
    PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
);

CREATE TABLE T_QRTZ_PAUSED_TRIGGER_GRPS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    TRIGGER_GROUP  VARCHAR(200) NOT NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
);

CREATE TABLE T_QRTZ_FIRED_TRIGGERS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    ENTRY_ID VARCHAR(95) NOT NULL,
    TRIGGER_NAME VARCHAR(200) NOT NULL,
    TRIGGER_GROUP VARCHAR(200) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    FIRED_TIME BIGINT(13) NOT NULL,
    SCHED_TIME BIGINT(13) NOT NULL,
    PRIORITY INTEGER NOT NULL,
    STATE VARCHAR(16) NOT NULL,
    JOB_NAME VARCHAR(200) NULL,
    JOB_GROUP VARCHAR(200) NULL,
    IS_NONCONCURRENT VARCHAR(1) NULL,
    REQUESTS_RECOVERY VARCHAR(1) NULL,
    PRIMARY KEY (SCHED_NAME,ENTRY_ID)
);

CREATE TABLE T_QRTZ_SCHEDULER_STATE
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    INSTANCE_NAME VARCHAR(200) NOT NULL,
    LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
    CHECKIN_INTERVAL BIGINT(13) NOT NULL,
    PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
);

CREATE TABLE T_QRTZ_LOCKS
(
    SCHED_NAME VARCHAR(120) NOT NULL,
    LOCK_NAME  VARCHAR(40) NOT NULL,
    PRIMARY KEY (SCHED_NAME,LOCK_NAME)
);


commit;

SELECT * FROM T_QRTZ_JOB_DETAILS;

SELECT * FROM T_QRTZ_CRON_TRIGGERS;

SELECT * FROM T_QRTZ_SIMPLE_TRIGGERS;

SELECT * FROM T_QRTZ_TRIGGERS ORDER BY DESCRIPTION;

SELECT * FROM T_QRTZ_FIRED_TRIGGERS;

SELECT * FROM T_QRTZ_SCHEDULER_STATE;

SELECT * FROM T_QRTZ_LOCKS;

SELECT  qt.SCHED_NAME as 'SCHED_NAME',
        qt.JOB_NAME as 'JOB_ID',
        qjd.JOB_GROUP,
        qjd.DESCRIPTION as 'JOB_NAME',
        qjd.JOB_CLASS_NAME,
        qt.DESCRIPTION as 'TRIGGER_NAME',
        qct.CRON_EXPRESSION,
        DATE_ADD(FROM_UNIXTIME(qt.START_TIME/1000), INTERVAL +9 HOUR) as 'start_time_local',
        DATE_ADD(FROM_UNIXTIME(qt.PREV_FIRE_TIME/1000), INTERVAL +9 HOUR ) as 'prev_fire_time_local',
        DATE_ADD(FROM_UNIXTIME(qt.NEXT_FIRE_TIME/1000), INTERVAL +9 HOUR) as 'next_fire_time_local'
  FROM  T_QRTZ_TRIGGERS qt,
        T_QRTZ_JOB_DETAILS qjd,
        T_QRTZ_CRON_TRIGGERS qct
 WHERE  qt.JOB_NAME = qjd.JOB_NAME
   AND  qt.TRIGGER_NAME = qct.TRIGGER_NAME
;

3. Trouble Shooting

3.1 org.quartz.SchedulerException: Job instantiation failed

기본생성자가 없을 때

org.quartz.SchedulerException: Job instantiation failed
	at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:47)
	at org.quartz.core.JobRunShell.initialize(JobRunShell.java:127)
	at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:392)
Caused by: java.lang.NoSuchMethodException: com.bys.service.console.job.VolumeSnapshotJob.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at org.springframework.util.ReflectionUtils.accessibleConstructor(ReflectionUtils.java:185)
	at org.springframework.scheduling.quartz.AdaptableJobFactory.createJobInstance(AdaptableJobFactory.java:61)
	at org.springframework.scheduling.quartz.SpringBeanJobFactory.createJobInstance(SpringBeanJobFactory.java:92)
	at com.bys.config.SchedulerJobFactory.createJobInstance(SchedulerJobFactory.java:20)
	at org.springframework.scheduling.quartz.AdaptableJobFactory.newJob(AdaptableJobFactory.java:43)
	... 2 common frames omitted

기본생성자를 추가했을 때

public VolumeSnapshotJob(){}
private VolumeService volumeService;
public VolumeSnapshotJob(VolumeService volumeService){
    this.volumeService = volumeService;
}

java.lang.NullPointerException: null
	at com.kakaoi.service.console.job.VolumeSnapshotJob.execute(VolumeSnapshotJob.java:41)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)

2022-04-19 17:10:05.229 ERROR 57636 --- [eduler_Worker-1] org.quartz.core.ErrorLogger              : Job (group1.61683eea-f7e1-4052-b21b-e8eaaf122358 threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.
	at org.quartz.core.JobRunShell.run(JobRunShell.java:213)
	at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
Caused by: java.lang.NullPointerException: null
	at com.kakaoi.service.console.job.VolumeSnapshotJob.execute(VolumeSnapshotJob.java:41)
	at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
	... 1 common frames omitted

최종 호출 되었을 때

Caused by: java.util.NoSuchElementException: No value present





Reference

  • http://www.quartz-scheduler.org/documentation/quartz-2.3.0/quick-start-guide.html
  • http://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration/
  • http://www.quartz-scheduler.org/documentation/quartz-2.3.0/cookbook/
  • https://onloadcode.com/quartz-scheduler-using-rest-api-with-spring-boot-and-mongodb/

Tag: [ programming  quartz  springboot  ]