Quartz 使用记录
Quartz 使用记录
官网
https://www.quartz-scheduler.org/
参考文档
什么是 Quartz?
官方描述:
Quartz is a richly featured, open source job scheduling library that can be integrated within virtually any Java application - from the smallest stand-alone application to the largest e-commerce system. Quartz can be used to create simple or complex schedules for executing tens, hundreds, or even tens-of-thousands of jobs; jobs whose tasks are defined as standard Java components that may execute virtually anything you may program them to do. The Quartz Scheduler includes many enterprise-class features, such as support for JTA transactions and clustering.
翻译:
Quartz 是一个有丰富特性,开源任务调度库,能和任意(从单个小应用到大型系统.) Java 应用集成.Quartz 用于创建简单或者混合 调度器用于执行数以千计的任务.Quartz Scheduler 包含了很多企业级特性,例如支持 JTA.
单例使用
1.下载 Jar 包
下载地址 :https://www.quartz-scheduler.org/downloads/
或者 引入pom 依赖:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- 日志简单实现 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.32</version>
<scope>compile</scope>
</dependency>
2. 将解压后lib文件夹下的 quartz-2.3.0-SNAPSHOT.jar 放于 Java 工程中
需下载 slf4j-simple.jar 包,否则使用SLF4j打印日志会报错:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
3. 配置 quartz.properties
在 classpath 添加 quartz.properties 文件,添加配置信息:
# 调度器名字
org.quartz.scheduler.instanceName = black-scheduler
# 线程池大小
org.quartz.threadPool.threadCount = 3
# 任务存储方式(RAMJobStore : 内存存储)
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
更详细配置参见 https://www.quartz-scheduler.org/documentation/quartz-2.3.0/configuration
4.编写HelloJob.java任务类
package org.black.demo.quartz;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloJob implements Job{
private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount());
LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}
5.编写 QuartzScheduleDemo 测试类
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
6.测试
测试结果:
[main] INFO org.quartz.impl.StdSchedulerFactory - Using default implementation for ThreadExecutor
[main] INFO org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
[main] INFO org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.3.0 created.
[main] INFO org.quartz.simpl.RAMJobStore - RAMJobStore initialized.
[main] INFO org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.3.0) 'black-schedule' with instanceId 'NON_CLUSTERED'
Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
NOT STARTED.
Currently in standby mode.
Number of jobs executed: 0
Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'black-schedule' initialized from default resource file in Quartz package: 'quartz.properties'
[main] INFO org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.3.0
[main] INFO org.quartz.core.QuartzScheduler - Scheduler black-schedule_$_NON_CLUSTERED started.
[main] INFO org.black.demo.quartz.QuartzScheduleDemo - Quartz 调度器启动时间:Tue Dec 28 11:51:03 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463495
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:07
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:07 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:03
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@4dab129f
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:03,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例ID1640663463496
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@4a5fecdf
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:51:03
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:51:11
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:51:11 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:51:07
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@5a318665
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:51:07,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务
Cron 表达式触发器
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCronTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCronTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
// cron 表达式: 秒 分 时 日 月 周 年
.withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * * * ? *"))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
withSchedule 方法可以设置不同的触发器类型.CronScheduleBuilder 继承自 ScheduleBuilder,ScheduleBuilder 的子类一共有4个,也就是可以设置 4中类型的触发器.
Calendar 触发器
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.CalendarIntervalScheduleBuilder;
import org.quartz.CronScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz Calendar 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleCalendarTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleCalendarTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(CalendarIntervalScheduleBuilder.calendarIntervalSchedule().withIntervalInSeconds(10))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
Daily Time 触发器
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.DailyTimeIntervalScheduleBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TimeOfDay;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz daily time 触发器示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleDailyTimeTriggerDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleDailyTimeTriggerDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 10s 执行一次任务,到 11点27分停止触发
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(DailyTimeIntervalScheduleBuilder.dailyTimeIntervalSchedule().withIntervalInSeconds(10)
.endingDailyAt(TimeOfDay.hourAndMinuteOfDay(11, 27)))
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}", date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
JDBC JobStore
上边的示例都是存储在内存中,这里展示了如何存储在数据库中.
1. 执行建表语句
数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下.我这里使用的是mysql 数据库,选择tables_mysql_innodb.sql 脚本执行.脚本内容如下:
DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;
CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) 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))
ENGINE=InnoDB;
CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
JOB_NAME VARCHAR(190) NOT NULL,
JOB_GROUP VARCHAR(190) 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(190) 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 QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) 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 QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) 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 QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(190) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;
CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(190) NOT NULL,
TRIGGER_GROUP VARCHAR(190) NOT NULL,
INSTANCE_NAME VARCHAR(190) 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(190) NULL,
JOB_GROUP VARCHAR(190) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;
CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(190) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;
CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;
CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
commit;
2.引入 mysql 驱动包
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
3.配置 quartz-jdbc.properties
## Quartz 配置信息
# 调度器名字
org.quartz.scheduler.instanceName = black-schedule
# 线程池大小
org.quartz.threadPool.threadCount = 3
# ====================================================================================== #
# 任务存储方式选择 JDBC存储(对应sql在 org.quartz.impl.jdbcjobstore.Constants 常量类中)
# JDBC 存储有两个实现 JobStoreCMT 和 JobStoreXT ,其中:
# JobStoreCMT:使用JTA容器管理事务,自己并不处理事务提交和回滚
# JobStoreTX: 通过 JDBC 自己管理事务提交和回滚,适合单体应用.
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
# 数据库驱动委派类(必须配置)
# org.quartz.impl.jdbcjobstore.StdJDBCDelegate (for fully JDBC-compliant drivers)
# org.quartz.impl.jdbcjobstore.MSSQLDelegate (for Microsoft SQL Server, and Sybase)
# org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
# org.quartz.impl.jdbcjobstore.WebLogicDelegate (for WebLogic drivers)
# org.quartz.impl.jdbcjobstore.oracle.OracleDelegate
# org.quartz.impl.jdbcjobstore.oracle.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.oracle.weblogic.WebLogicOracleDelegate (for Oracle drivers used within Weblogic)
# org.quartz.impl.jdbcjobstore.CloudscapeDelegate
# org.quartz.impl.jdbcjobstore.DB2v6Delegate
# org.quartz.impl.jdbcjobstore.DB2v7Delegate
# org.quartz.impl.jdbcjobstore.DB2v8Delegate
# org.quartz.impl.jdbcjobstore.HSQLDBDelegate
# org.quartz.impl.jdbcjobstore.PointbaseDelegate
# org.quartz.impl.jdbcjobstore.SybaseDelegate
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# 数据源配置(必须配置) blackQuartz 是数据源名字
org.quartz.jobStore.dataSource = blackQuartz
# Quartz 表前缀
org.quartz.jobStore.tablePrefix=QRTZ_
# 指示 JobDataMaps 中的所有数据都是 String 类型,这样不用序列化存储到 BLOB 列中
org.quartz.jobStore.useProperties=false
# 多长时间认定 触发器错过了下次触发时间,默认 60000 毫秒
org.quartz.jobStore.misfireThreshold=60000
# 开启集群特性
org.quartz.jobStore.isClustered=false
# 集群检查频率间隔,默认15000毫秒
org.quartz.jobStore.clusterCheckinInterval=15000
# 一次性处理未触发的触发器最大数量,默认 20
org.quartz.jobStore.maxMisfiresToHandleAtATime=20
# 不允许 setAutoCommit(false) true-不允许,false-允许
org.quartz.jobStore.dontSetAutoCommitFalse=false
# 加锁查询 LOCKS 表的一行数据,{0}是表前缀(tablePrefix),{1}是调度器名字
org.quartz.jobStore.selectWithLockSQL="SELECT * FROM {0}LOCKS WHERE SCHED_NAME = {1} AND LOCK_NAME = ? FOR UPDATE"
# 设置事务隔离级别为串行 true-设置,false-不设置
org.quartz.jobStore.txIsolationLevelSerializable=false
# 如果 org.quartz.scheduler.batchTriggerAcquisitionMaxCount >1 那么此属性必须设置为 true
org.quartz.jobStore.acquireTriggersWithinLock=false
# 锁处理类,用于生产 Semaphore 实例在 job store data 上进行锁控制
#org.quartz.jobStore.lockHandler.class=null
# 管道分隔的属性集合 在初始化阶段传给DriverDelegate使用,格式:"settingName=settingValue|otherSettingName=otherSettingValue|..."
#org.quartz.jobStore.driverDelegateInitString=
# ====================================================================================== #
# ====================================================================================== #
# 数据源名字为blackQuartz的 数据源配置(数据库初始化脚本在quartz-2.3.0.jar的/org/quartz/impl/jdbcjobstore/包下)
# ====================================================================================== #
org.quartz.dataSource.blackQuartz.driver = com.mysql.cj.jdbc.Driver
org.quartz.dataSource.blackQuartz.URL = jdbc:mysql://localhost:3306/black?characterEncoding=UTF8&connectTimeout=6000&socketTimeout=6000&connectionTimeZone=Asia/Shanghai
org.quartz.dataSource.blackQuartz.user = black
org.quartz.dataSource.blackQuartz.password = Black@123
org.quartz.dataSource.blackQuartz.maxConnections = 5
org.quartz.dataSource.blackQuartz.validationQuery=select 0
4.编写测试类
package org.black.demo.quartz;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloJob implements Job{
private static final Logger LOGGER = LoggerFactory.getLogger(HelloJob.class);
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
LOGGER.info("任务明细:{}", context.getJobDetail());
LOGGER.info("激活的实例ID{}",context.getFireInstanceId());
Date d =context.getFireTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
LOGGER.info("调度器:{}",context.getScheduler());
LOGGER.info("调度器激活时间:{}",f.format(context.getScheduledFireTime()));
if(context.getPreviousFireTime() != null) {
LOGGER.info("上次调用时间:{}",f.format(context.getPreviousFireTime()));
}
LOGGER.info("下次调用时间:{}",f.format(context.getNextFireTime()));
LOGGER.info("触发器:{}",context.getTrigger());
LOGGER.info("触发时间:{}", f.format(d));
LOGGER.info("job 实例:{}", context.getJobInstance());
LOGGER.info("job 运行时长:{}s", context.getJobRunTime());
LOGGER.info("Job 设置的返回结果:{}",context.getResult());
LOGGER.info("MergedJobDataMap:{}", context.getMergedJobDataMap());
//
// LOGGER.info("恢复任务时对应的触发器key:{}",context.getRecoveringTriggerKey());
LOGGER.info("重复激活次数:{}",context.getRefireCount());
LocalDateTime date = LocalDateTime.now();
String curDateTime = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LOGGER.info("时间:{},当前线程:{} - 执行 HelloJob 任务",curDateTime,Thread.currentThread().getName() );
}
}
package org.black.demo.quartz;
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Quartz 示例
*
* @author lihw
* @date 2021-12-27 17:48:011
*/
public class QuartzScheduleJDBCDemo {
private static final Logger LOGGER = LoggerFactory.getLogger(QuartzScheduleJDBCDemo.class);
public static void main(String[] args) {
try {
// 从工厂类获取调度器示例
StdSchedulerFactory factory = new StdSchedulerFactory();
// 指定加载quartz-jdbc.properties配置
factory.initialize("quartz-jdbc.properties");
Scheduler scheduler = factory.getScheduler();
// 启动调度器
scheduler.start();
// 定义一个Job 绑定到 HelloJob.class
JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
// 定义一个触发器,每 4s 执行一次任务
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startNow()
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(4).repeatForever())
.build();
// 调度器调度任务
Date date = scheduler.scheduleJob(job, trigger);
LOGGER.info("Quartz 调度器启动时间:{}",date);
// 调用shutdown()方法关闭调度器,否则任务一直在运行
// scheduler.shutdown();
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
5. 测试
控制台输出:
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:05,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163286
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:05
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:13 CST 2021
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:09
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@f8b8a7d
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-2] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:09,当前线程:black-schedule_Worker-2 - 执行 HelloJob 任务
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163287
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:09
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:17
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:17 CST 2021
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:13
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@7a800c47
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-3] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:13,当前线程:black-schedule_Worker-3 - 执行 HelloJob 任务
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 任务明细:JobDetail 'group1.job1': jobClass: 'org.black.demo.quartz.HelloJob concurrentExectionDisallowed: false persistJobDataAfterExecution: false isDurable: false requestsRecovers: false
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 激活的实例IDNON_CLUSTERED1640663163288
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器:org.quartz.impl.StdScheduler@480a4a2d
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 调度器激活时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 上次调用时间:2021-12-28 11:46:13
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 下次调用时间:2021-12-28 11:46:21
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发器:Trigger 'group1.trigger1': triggerClass: 'org.quartz.impl.triggers.SimpleTriggerImpl calendar: 'null' misfireInstruction: 0 nextFireTime: Tue Dec 28 11:46:21 CST 2021
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 触发时间:2021-12-28 11:46:17
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 实例:org.black.demo.quartz.HelloJob@1053e9f7
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - job 运行时长:-1s
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - Job 设置的返回结果:null
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - MergedJobDataMap:org.quartz.JobDataMap@0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 重复激活次数:0
[black-schedule_Worker-1] INFO org.black.demo.quartz.HelloJob - 时间:2021-12-28 11:46:17,当前线程:black-schedule_Worker-1 - 执行 HelloJob 任务
执行以下sql查询 表数据:
select * from QRTZ_JOB_DETAILS;
select * from QRTZ_FIRED_TRIGGERS;
select * from QRTZ_PAUSED_TRIGGER_GRPS;
select * from QRTZ_SCHEDULER_STATE;
select * from QRTZ_LOCKS;
select * from QRTZ_SIMPLE_TRIGGERS;
select * from QRTZ_SIMPROP_TRIGGERS;
select * from QRTZ_CRON_TRIGGERS;
select * from QRTZ_BLOB_TRIGGERS;
select * from QRTZ_TRIGGERS;
select * from QRTZ_JOB_DETAILS;
select * from QRTZ_CALENDARS;
SpringBoot 集成
待续...
Quartz 使用记录的更多相关文章
- Quartz 学习记录1
原因 公司有一些批量定时任务可能需要在夜间执行,用的是quartz和spring batch两个框架.quartz是个定时任务框架,spring batch是个批处理框架. 虽然我自己的小玩意儿平时不 ...
- quartz 实例记录
之前介绍过了quartz的一些相关理论知识,感觉上挺简单的,实际动手操作也确实如此,去quartz的官网上把Jar包下载下来以后,会看到它的目录里有例子程序,看完第一个例子觉得还可以,但是看后面两个例 ...
- quartz相关记录
1.http://www.quartz-scheduler.org/api/2.3.1-SNAPSHOT/ api地址 2.https://www.jianshu.com/p/3c3e166a7da1 ...
- Quartz使用记录总结
Quartz是一个任务调度框架,最近在项目中有用到,所以做个记录总结. 一.主要元素 Scheduler:调度器,控制任务的调度,将JobDetail和Trigger注册到Scheduler加以控制. ...
- quartz问题记录-missed their scheduled fire-time
这里有3个原因:1.所有的woker thread(工作线程; 辅助线程)都在运行其他的job2.scheduler(调度器)down了(关于这个down.我不太明确是shutdown了..还是挂掉了 ...
- Quartz学习记录
参考资料: 官方网站 Quartz使用总结
- Quartz任务调度 服务日志+log4net打印日志+制作windows服务
引言 现在许多的项目都需要定时的服务进行支撑,而我们经常用到的定时服务就是Quartz任务调度了.不过我们在使用定时Job进行获取的时候,有时候我们就需要记录一下自定义的日志,甚至我们还会对执行定时J ...
- Quartz SpringBoot 简单整合一下
一次简单的代码整合记录. 数据库准备 如果是MySQL可能出现一些小问题.比如联合主键长度超限制,已经记录解决办法了. CREATE TABLE QRTZ_JOB_DETAILS ( SCHED_NA ...
- Quartz.net使用记录
1.引入dll文件: nuget控制台:安装quartz:Install-Package Quartz 安装log4net:Install-Package log4net,这里使用log4net记录一 ...
随机推荐
- Python基础练习之购物车
#前置知识点 # enumerate(LIST) # 输出一个元组,第一个为下标,第二个为元素 # a = [1, 2, 3, 4] # for i in enumerate(a): # print( ...
- [MySQL]MySQL8.0的一些注意事项以及解决方案
MySQL8.0 注意事项以及解决方案 1. MySQL8.0 修改大小写敏感配置 天坑MySQL8.0! 在安装后, 便无法通过修改配置文件,重启服务,或者执行sql来更改数据库配置, 要想配置的话 ...
- 6月5日 python复习 模块
"""1. os和sys都是干什么的?2. 你工作中都用过哪些内置模块?3. 有没有用过functools模块?"""1. os 系统相关 ...
- sql server 2000 单主键高效分页存储过程 (支持多字段排序)
sql server 2000 单主键高效分页存储过程 (支持多字段排序) Create PROC P_viewPage /* nzperfect [ ...
- var、let和const区别
var.let和const区别 变量提升问题 var声明的变量存在变量提升,而let与const声明的变量不存在变量提升,但存在暂时性死区 即在预编译阶段,js引擎扫描代码时,遇到变量声明,会把var ...
- 【网鼎杯】jocker--部分代码加壳逆向处理
Main函数,用户输入flag,长度为24位 Wrong函数进行了简单的异或操作 Omg函数进行异或操作,根据提示来看应该是假check Encrypt无法生成伪代码 发现有加壳以及自修改,下断点动调 ...
- 什么是Java序列化,如何实现Java序列化?或者请解释Serializable接口的作用?
象序列化的目标是将对象保存到磁盘中,或允许在网络中直接传输对象,对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上,通过网络将这种二进制流传输到另 ...
- 什么是RabbitMQ?RabbitMQ的使用场景是什么?
参考链接:RabbitMQ 简介以及使用场景
- Java中自动装箱与拆箱
一.什么是封装类? Java中存在基础数据类型,但是在某些情况下,我们要对基础数据类型进行对象的操作,例如,集合中只能存在对象,而不能存在基础数据类型,于是便出现了包装器类.包装器类型就是对基本数据类 ...
- 使用docker-compose+nginx+uwsgi+django部署项目
(1)centos上下载docker + docker-compose (2)基础目录 (3)首先创建一个纯净的python+django+uwsgi的镜像,便于后期使用(也可不用创建,后期docke ...