在分布式系统中调度指定时间的任务
Schedule time-specified tasks in distributed system
我对具有不同执行时间的任务使用 ScheduledThreadPoolExecutor
。例如,一项任务安排在今晚 9:30 下午,另一项任务安排在明天 8:00 上午。但是如果服务器由于某种原因关闭,任务就会消失。
我正在考虑数据库中的任务持久性,以便我可以在以后重新触发失败的任务——但我想这不是一个完美的解决方案。
有什么好的框架或其他建议吗?
您可以使用 quartz scheduler 基于特殊 java 的库来调度任务。
这是该网站的链接
此库可用于任何 java 开发环境,例如 IntelliJ IDEA、Netbeans 或 日食.
可以使用类似Redisson. It also supports quartz cron experssions. Here is documentation的基于Redis的任务调度框架
下面是概念验证应用程序的代码,它实现了您在问题中指定的内容。它使用 Quartz 作为调度器,使用 H2 作为底层数据库。我假设 Maven 标准 file/folder 结构。
这是一个命令行应用程序,它接受来自标准输入的行,每行指定触发前等待的秒数以及随后打印的内容(因此您输入“15 hello, world!”并按回车键,它将安排在 15 秒内打印 "hello, world!",您可以安排多个任务而无需等待其中任何一个完成)。如果您在任务被触发之前终止应用程序,然后再次 运行 应用程序,它们将 运行 在指定的时间(如果尚未通过)或立即(如果已经通过)。
1) src/main/java/App.java
:
import java.io.*;
import java.sql.*;
import java.util.*;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.util.IOUtils;
import org.quartz.*;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.impl.StdSchedulerFactory;
public class App {
public static class PrintJob implements Job {
public void execute(JobExecutionContext ctx)
throws JobExecutionException {
System.out.println(ctx.getJobDetail().getJobDataMap()
.get("message"));
}
}
public static void main(String[] args) throws SchedulerException,
ClassNotFoundException, SQLException, IOException {
setUpDb();
try (Scanner scanner = new Scanner(System.in)) {
SchedulerFactory schedFactory = new StdSchedulerFactory();
Scheduler sched = schedFactory.getScheduler();
sched.start();
while (true) {
int dt = scanner.nextInt();
String s = scanner.nextLine().trim();
JobDetail jd =
JobBuilder.newJob(PrintJob.class)
.withIdentity(UUID.randomUUID().toString())
.usingJobData("message", s).build();
Trigger trigger =
TriggerBuilder
.newTrigger()
.startAt(
DateBuilder.futureDate(dt, IntervalUnit.SECOND))
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withMisfireHandlingInstructionFireNow())
.build();
sched.scheduleJob(jd, trigger);
}
}
}
private static void setUpDb() throws ClassNotFoundException, IOException,
SQLException, UnsupportedEncodingException {
Class.forName("org.h2.Driver");
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:~/my_db");
ds.setUser("sa");
ds.setPassword("");
InputStream in =
App.class.getClassLoader().getResourceAsStream("tables_h2.sql");
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copyAndClose(in, out);
try (Connection conn = ds.getConnection()) {
try {
conn.createStatement().executeQuery(
"select count(*) from QRTZ_JOB_DETAILS");
} catch (Exception e) {
conn.createStatement().executeUpdate(
new String(out.toByteArray(), "utf-8"));
}
}
}
}
2) src/main/resources/quartz.properties
:
org.quartz.threadPool.threadCount=3
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=qrtz_
org.quartz.dataSource.myDS.driver=org.h2.Driver
org.quartz.dataSource.myDS.URL=jdbc:h2:~/my_db;MVCC=true
org.quartz.dataSource.myDS.user=sa
org.quartz.dataSource.myDS.password=
org.quartz.dataSource.myDS.maxConnections=3
3) src/main/resources/tables_h2.sql
(取自 quartz 2.2.3 发行版,文件夹 docs/dbTables
):
-- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database,
-- and verifying that it works with Quartz's StdJDBCDelegate
--
-- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE
-- setting on your H2 database, or you will experience dead-locks
--
--
-- In your Quartz properties file, you'll need to set
-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR (200) NOT NULL ,
CALENDAR IMAGE NOT NULL
);
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
CRON_EXPRESSION VARCHAR (120) NOT NULL ,
TIME_ZONE_ID VARCHAR (80)
);
CREATE TABLE 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 NOT NULL ,
SCHED_TIME BIGINT NOT NULL ,
PRIORITY INTEGER NOT NULL ,
STATE VARCHAR (16) NOT NULL,
JOB_NAME VARCHAR (200) NULL ,
JOB_GROUP VARCHAR (200) NULL ,
IS_NONCONCURRENT BOOLEAN NULL ,
REQUESTS_RECOVERY BOOLEAN NULL
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL
);
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR (200) NOT NULL ,
LAST_CHECKIN_TIME BIGINT NOT NULL ,
CHECKIN_INTERVAL BIGINT NOT NULL
);
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR (40) NOT NULL
);
CREATE TABLE 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 BOOLEAN NOT NULL ,
IS_NONCONCURRENT BOOLEAN NOT NULL ,
IS_UPDATE_DATA BOOLEAN NOT NULL ,
REQUESTS_RECOVERY BOOLEAN NOT NULL ,
JOB_DATA IMAGE NULL
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
REPEAT_COUNT BIGINT NOT NULL ,
REPEAT_INTERVAL BIGINT NOT NULL ,
TIMES_TRIGGERED BIGINT NOT NULL
);
CREATE TABLE 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 INTEGER NULL,
INT_PROP_2 INTEGER 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 BOOLEAN NULL,
BOOL_PROP_2 BOOLEAN NULL,
);
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
BLOB_DATA IMAGE NULL
);
CREATE TABLE 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 NULL ,
PREV_FIRE_TIME BIGINT NULL ,
PRIORITY INTEGER NULL ,
TRIGGER_STATE VARCHAR (16) NOT NULL ,
TRIGGER_TYPE VARCHAR (8) NOT NULL ,
START_TIME BIGINT NOT NULL ,
END_TIME BIGINT NULL ,
CALENDAR_NAME VARCHAR (200) NULL ,
MISFIRE_INSTR SMALLINT NULL ,
JOB_DATA IMAGE NULL
);
ALTER TABLE QRTZ_CALENDARS ADD
CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY
(
SCHED_NAME,
CALENDAR_NAME
);
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_FIRED_TRIGGERS ADD
CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
ENTRY_ID
);
ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS ADD
CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_SCHEDULER_STATE ADD
CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY
(
SCHED_NAME,
INSTANCE_NAME
);
ALTER TABLE QRTZ_LOCKS ADD
CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY
(
SCHED_NAME,
LOCK_NAME
);
ALTER TABLE QRTZ_JOB_DETAILS ADD
CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_TRIGGERS ADD
CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_TRIGGERS ADD
CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
) REFERENCES QRTZ_JOB_DETAILS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
COMMIT;
4) pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.ra</groupId>
<artifactId>so_qrtz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>so_qrtz</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
如果你想自定义你自己的版本而不是使用 Quartz 或 elastic-job,你所需要的只是一个地方来持久化作业列表和一个供工作人员获取的执行锁。作业包含作业详细信息和 cron 表达式。您可以使用 Redis、Zookeeper 或 ETCD 来实现分布式锁和作业列表持久化。
我对具有不同执行时间的任务使用 ScheduledThreadPoolExecutor
。例如,一项任务安排在今晚 9:30 下午,另一项任务安排在明天 8:00 上午。但是如果服务器由于某种原因关闭,任务就会消失。
我正在考虑数据库中的任务持久性,以便我可以在以后重新触发失败的任务——但我想这不是一个完美的解决方案。
有什么好的框架或其他建议吗?
您可以使用 quartz scheduler 基于特殊 java 的库来调度任务。
这是该网站的链接
此库可用于任何 java 开发环境,例如 IntelliJ IDEA、Netbeans 或 日食.
可以使用类似Redisson. It also supports quartz cron experssions. Here is documentation的基于Redis的任务调度框架
下面是概念验证应用程序的代码,它实现了您在问题中指定的内容。它使用 Quartz 作为调度器,使用 H2 作为底层数据库。我假设 Maven 标准 file/folder 结构。
这是一个命令行应用程序,它接受来自标准输入的行,每行指定触发前等待的秒数以及随后打印的内容(因此您输入“15 hello, world!”并按回车键,它将安排在 15 秒内打印 "hello, world!",您可以安排多个任务而无需等待其中任何一个完成)。如果您在任务被触发之前终止应用程序,然后再次 运行 应用程序,它们将 运行 在指定的时间(如果尚未通过)或立即(如果已经通过)。
1) src/main/java/App.java
:
import java.io.*;
import java.sql.*;
import java.util.*;
import org.h2.jdbcx.JdbcDataSource;
import org.h2.util.IOUtils;
import org.quartz.*;
import org.quartz.DateBuilder.IntervalUnit;
import org.quartz.impl.StdSchedulerFactory;
public class App {
public static class PrintJob implements Job {
public void execute(JobExecutionContext ctx)
throws JobExecutionException {
System.out.println(ctx.getJobDetail().getJobDataMap()
.get("message"));
}
}
public static void main(String[] args) throws SchedulerException,
ClassNotFoundException, SQLException, IOException {
setUpDb();
try (Scanner scanner = new Scanner(System.in)) {
SchedulerFactory schedFactory = new StdSchedulerFactory();
Scheduler sched = schedFactory.getScheduler();
sched.start();
while (true) {
int dt = scanner.nextInt();
String s = scanner.nextLine().trim();
JobDetail jd =
JobBuilder.newJob(PrintJob.class)
.withIdentity(UUID.randomUUID().toString())
.usingJobData("message", s).build();
Trigger trigger =
TriggerBuilder
.newTrigger()
.startAt(
DateBuilder.futureDate(dt, IntervalUnit.SECOND))
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withMisfireHandlingInstructionFireNow())
.build();
sched.scheduleJob(jd, trigger);
}
}
}
private static void setUpDb() throws ClassNotFoundException, IOException,
SQLException, UnsupportedEncodingException {
Class.forName("org.h2.Driver");
JdbcDataSource ds = new JdbcDataSource();
ds.setURL("jdbc:h2:~/my_db");
ds.setUser("sa");
ds.setPassword("");
InputStream in =
App.class.getClassLoader().getResourceAsStream("tables_h2.sql");
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copyAndClose(in, out);
try (Connection conn = ds.getConnection()) {
try {
conn.createStatement().executeQuery(
"select count(*) from QRTZ_JOB_DETAILS");
} catch (Exception e) {
conn.createStatement().executeUpdate(
new String(out.toByteArray(), "utf-8"));
}
}
}
}
2) src/main/resources/quartz.properties
:
org.quartz.threadPool.threadCount=3
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.dataSource=myDS
org.quartz.jobStore.tablePrefix=qrtz_
org.quartz.dataSource.myDS.driver=org.h2.Driver
org.quartz.dataSource.myDS.URL=jdbc:h2:~/my_db;MVCC=true
org.quartz.dataSource.myDS.user=sa
org.quartz.dataSource.myDS.password=
org.quartz.dataSource.myDS.maxConnections=3
3) src/main/resources/tables_h2.sql
(取自 quartz 2.2.3 发行版,文件夹 docs/dbTables
):
-- Thanks to Amir Kibbar and Peter Rietzler for contributing the schema for H2 database,
-- and verifying that it works with Quartz's StdJDBCDelegate
--
-- Note, Quartz depends on row-level locking which means you must use the MVCC=TRUE
-- setting on your H2 database, or you will experience dead-locks
--
--
-- In your Quartz properties file, you'll need to set
-- org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR (200) NOT NULL ,
CALENDAR IMAGE NOT NULL
);
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
CRON_EXPRESSION VARCHAR (120) NOT NULL ,
TIME_ZONE_ID VARCHAR (80)
);
CREATE TABLE 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 NOT NULL ,
SCHED_TIME BIGINT NOT NULL ,
PRIORITY INTEGER NOT NULL ,
STATE VARCHAR (16) NOT NULL,
JOB_NAME VARCHAR (200) NULL ,
JOB_GROUP VARCHAR (200) NULL ,
IS_NONCONCURRENT BOOLEAN NULL ,
REQUESTS_RECOVERY BOOLEAN NULL
);
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR (200) NOT NULL
);
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR (200) NOT NULL ,
LAST_CHECKIN_TIME BIGINT NOT NULL ,
CHECKIN_INTERVAL BIGINT NOT NULL
);
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR (40) NOT NULL
);
CREATE TABLE 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 BOOLEAN NOT NULL ,
IS_NONCONCURRENT BOOLEAN NOT NULL ,
IS_UPDATE_DATA BOOLEAN NOT NULL ,
REQUESTS_RECOVERY BOOLEAN NOT NULL ,
JOB_DATA IMAGE NULL
);
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
REPEAT_COUNT BIGINT NOT NULL ,
REPEAT_INTERVAL BIGINT NOT NULL ,
TIMES_TRIGGERED BIGINT NOT NULL
);
CREATE TABLE 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 INTEGER NULL,
INT_PROP_2 INTEGER 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 BOOLEAN NULL,
BOOL_PROP_2 BOOLEAN NULL,
);
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR (200) NOT NULL ,
TRIGGER_GROUP VARCHAR (200) NOT NULL ,
BLOB_DATA IMAGE NULL
);
CREATE TABLE 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 NULL ,
PREV_FIRE_TIME BIGINT NULL ,
PRIORITY INTEGER NULL ,
TRIGGER_STATE VARCHAR (16) NOT NULL ,
TRIGGER_TYPE VARCHAR (8) NOT NULL ,
START_TIME BIGINT NOT NULL ,
END_TIME BIGINT NULL ,
CALENDAR_NAME VARCHAR (200) NULL ,
MISFIRE_INSTR SMALLINT NULL ,
JOB_DATA IMAGE NULL
);
ALTER TABLE QRTZ_CALENDARS ADD
CONSTRAINT PK_QRTZ_CALENDARS PRIMARY KEY
(
SCHED_NAME,
CALENDAR_NAME
);
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
CONSTRAINT PK_QRTZ_CRON_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_FIRED_TRIGGERS ADD
CONSTRAINT PK_QRTZ_FIRED_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
ENTRY_ID
);
ALTER TABLE QRTZ_PAUSED_TRIGGER_GRPS ADD
CONSTRAINT PK_QRTZ_PAUSED_TRIGGER_GRPS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_SCHEDULER_STATE ADD
CONSTRAINT PK_QRTZ_SCHEDULER_STATE PRIMARY KEY
(
SCHED_NAME,
INSTANCE_NAME
);
ALTER TABLE QRTZ_LOCKS ADD
CONSTRAINT PK_QRTZ_LOCKS PRIMARY KEY
(
SCHED_NAME,
LOCK_NAME
);
ALTER TABLE QRTZ_JOB_DETAILS ADD
CONSTRAINT PK_QRTZ_JOB_DETAILS PRIMARY KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
CONSTRAINT PK_QRTZ_SIMPLE_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
CONSTRAINT PK_QRTZ_SIMPROP_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_TRIGGERS ADD
CONSTRAINT PK_QRTZ_TRIGGERS PRIMARY KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
);
ALTER TABLE QRTZ_CRON_TRIGGERS ADD
CONSTRAINT FK_QRTZ_CRON_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_SIMPLE_TRIGGERS ADD
CONSTRAINT FK_QRTZ_SIMPLE_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_SIMPROP_TRIGGERS ADD
CONSTRAINT FK_QRTZ_SIMPROP_TRIGGERS_QRTZ_TRIGGERS FOREIGN KEY
(
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) REFERENCES QRTZ_TRIGGERS (
SCHED_NAME,
TRIGGER_NAME,
TRIGGER_GROUP
) ON DELETE CASCADE;
ALTER TABLE QRTZ_TRIGGERS ADD
CONSTRAINT FK_QRTZ_TRIGGERS_QRTZ_JOB_DETAILS FOREIGN KEY
(
SCHED_NAME,
JOB_NAME,
JOB_GROUP
) REFERENCES QRTZ_JOB_DETAILS (
SCHED_NAME,
JOB_NAME,
JOB_GROUP
);
COMMIT;
4) pom.xml
:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ru.ra</groupId>
<artifactId>so_qrtz</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>so_qrtz</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.187</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
如果你想自定义你自己的版本而不是使用 Quartz 或 elastic-job,你所需要的只是一个地方来持久化作业列表和一个供工作人员获取的执行锁。作业包含作业详细信息和 cron 表达式。您可以使用 Redis、Zookeeper 或 ETCD 来实现分布式锁和作业列表持久化。