美文网首页
Quartz任务调度使用

Quartz任务调度使用

作者: Anson_1f2a | 来源:发表于2022-01-06 21:54 被阅读0次

继上篇文章记录了XXL-JOB的使用后,但在服务器多节点部署的情况下始终无法生效,可能是因为docker环境导致网络没有打通,原因不明~于是放弃,改用Quartz。
以下记录开发过程。

1. 数据库准备

前往官网下载压缩包(http://www.quartz-scheduler.org/downloads/
我下载的是2.2.3版,因为2.3.0版本的压缩包里面没有相关sql文件。
我不使用项目的库,所以新建一个叫quartz_job的库,然后执行一下sql。

CREATE SCHEMA `quartz_job` DEFAULT CHARACTER SET utf8mb4;
USE `quartz_job`;
#
# In your Quartz properties file, you'll need to set 
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#
#
# By: Ron Cordell - roncordell
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.

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(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))
ENGINE=InnoDB;

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(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 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(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 QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

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),
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(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 QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

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 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(200) 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(200) 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(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))
ENGINE=InnoDB;

CREATE TABLE 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))
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. Maven依赖

因为使用了spring boot framework,所以加入下面依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

3. 配置quartz

修改application.yml文件

spring:
  quartz:
    properties:
      org:
        quartz:
          scheduler:
            instanceName: MyScheduler
            instanceId: AUTO
          jobStore:
            class: org.quartz.impl.jdbcjobstore.JobStoreTX
            driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
            tablePrefix: QRTZ_
            isClustered: true
            clusterCheckinInterval: 10000
            dataSource: quartz_job
            #以指示JDBCJobStore将JobDataMaps中的所有值都作为字符串,因此可以作为名称
            #- 值对存储而不是在BLOB列中以其序列化形式存储更多复杂的对象。
            #从长远来看,这是更安全的,因为您避免了将非String类序列化为BLOB的类版本问题。
            useProperties: false
          threadPool:
            class: org.quartz.simpl.SimpleThreadPool
            threadCount: 10
            threadPriority: 5
            threadsInheritContextClassLoaderOfInitializingThread: true
          dataSource:
            quartz_job:
              URL: jdbc:mysql://127.0.0.1:3306/quartz_job?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
              user: root
              password: 123456
              driver: com.mysql.cj.jdbc.Driver
              provider: hikaricp

4. 添加执行器

import org.apache.logging.log4j.LogManager
import org.quartz.Job
import org.quartz.JobExecutionContext

/**
 * @Author  Anson
 * @Date  2022/1/6 17:13
 * @Version 1.0
 */
class MyQuartzJob : Job {
    private val logger = LogManager.getLogger()

    override fun execute(p0: JobExecutionContext?) {
        logger.info("test job")
    }
}

5. 实现Quartz接口,方便创建与执行任务

DTO

data class QuartzConfigDTO(
    /**
     * 任务名称
     */
    val jobName: String,
    /**
     * 任务所属组
     */
    val groupName: String,
    /**
     * 任务执行类
     */
    val jobClass: String,
    /**
     * 任务调度时间表达式
     */
    val cronExpression: String,
    /**
     * 附加参数
     */
    val param: Map<String, Any>
) : Serializable

Interface

/**
 * @Author  Anson
 * @Date  2022/1/6 17:22
 * @Version 1.0
 */
interface JobService {
    /**
     * 添加任务可以传参数
     * @param clazzName
     * @param jobName
     * @param groupName
     * @param cronExp
     * @param param
     */
    fun addJob(clazzName: String, jobName: String, groupName: String, cronExp: String, param: Map<String, Any>)

    /**
     * 暂停任务
     * @param jobName
     * @param groupName
     */
    fun pauseJob(jobName: String, groupName: String)

    /**
     * 恢复任务
     * @param jobName
     * @param groupName
     */
    fun resumeJob(jobName: String, groupName: String)

    /**
     * 立即运行一次定时任务
     * @param jobName
     * @param groupName
     */
    fun runOnce(jobName: String, groupName: String)

    /**
     * 更新任务
     * @param jobName
     * @param groupName
     * @param cronExp
     * @param param
     */
    fun updateJob(jobName: String, groupName: String, cronExp: String?, param: Map<String, Any>?)

    /**
     * 删除任务
     * @param jobName
     * @param groupName
     */
    fun deleteJob(jobName: String, groupName: String)

    /**
     * 启动所有任务
     */
    fun startAllJobs()

    /**
     * 暂停所有任务
     */
    fun pauseAllJobs()

    /**
     * 恢复所有任务
     */
    fun resumeAllJobs()

    /**
     * 关闭所有任务
     */
    fun shutdownAllJobs()
}

Service

/**
 * @Author  Anson
 * @Date  2022/1/6 17:23
 * @Version 1.0
 */
@Component
class JobServiceImpl(
    private val scheduler: Scheduler
) : JobService {
    private val logger = LogManager.getLogger()

    override fun addJob(
        clazzName: String,
        jobName: String,
        groupName: String,
        cronExp: String,
        param: Map<String, Any>
    ) {
        try {
            //构建job信息
            val jobClass: Class<out Job> = Class.forName(clazzName) as Class<out Job>
            val jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, groupName).build()
            //表达式调度构建器(即任务执行的时间)
            val scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp)
            //按新的cronExpression表达式构建一个新的trigger
            val trigger: CronTrigger =
                TriggerBuilder.newTrigger().withIdentity(jobName, groupName).withSchedule(scheduleBuilder).build()
            //获得JobDataMap,写入数据
            trigger.jobDataMap.putAll(param)
            scheduler.scheduleJob(jobDetail, trigger)
        } catch (e: Exception) {
            logger.error("创建任务失败", e)
        }
    }

    override fun pauseJob(jobName: String, groupName: String) {
        try {
            scheduler.pauseJob(JobKey.jobKey(jobName, groupName))
        } catch (e: SchedulerException) {
            logger.error("暂停任务失败", e)
        }
    }

    override fun resumeJob(jobName: String, groupName: String) {
        try {
            scheduler.resumeJob(JobKey.jobKey(jobName, groupName))
        } catch (e: SchedulerException) {
            logger.error("恢复任务失败", e)
        }
    }

    override fun runOnce(jobName: String, groupName: String) {
        try {
            scheduler.triggerJob(JobKey.jobKey(jobName, groupName))
        } catch (e: SchedulerException) {
            logger.error("立即运行一次定时任务失败", e)
        }
    }

    override fun updateJob(jobName: String, groupName: String, cronExp: String?, param: Map<String, Any>?) {
        try {
            val triggerKey = TriggerKey.triggerKey(jobName, groupName)
            var trigger: CronTrigger = scheduler.getTrigger(triggerKey) as CronTrigger
            if (cronExp != null) {
                // 表达式调度构建器
                val scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp)
                // 按新的cronExpression表达式重新构建trigger
                trigger = trigger.triggerBuilder.withIdentity(triggerKey).withSchedule(scheduleBuilder).build()
            }
            //修改map
            if (param != null) {
                trigger.jobDataMap.putAll(param)
            }
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger)
        } catch (e: Exception) {
            logger.error("更新任务失败", e)
        }
    }

    override fun deleteJob(jobName: String, groupName: String) {
        try {
            //暂停、移除、删除
            scheduler.pauseTrigger(TriggerKey.triggerKey(jobName, groupName))
            scheduler.unscheduleJob(TriggerKey.triggerKey(jobName, groupName))
            scheduler.deleteJob(JobKey.jobKey(jobName, groupName))
        } catch (e: Exception) {
            logger.error("删除任务失败", e)
        }
    }

    override fun startAllJobs() {
        try {
            scheduler.start()
        } catch (e: Exception) {
            logger.error("开启所有的任务失败", e)
        }
    }

    override fun pauseAllJobs() {
        try {
            scheduler.pauseAll()
        } catch (e: Exception) {
            logger.error("暂停所有任务失败", e)
        }
    }

    override fun resumeAllJobs() {
        try {
            scheduler.resumeAll()
        } catch (e: Exception) {
            logger.error("恢复所有任务失败", e)
        }
    }

    override fun shutdownAllJobs() {
        try {
            if (!scheduler.isShutdown) {
                // 需谨慎操作关闭scheduler容器
                // scheduler生命周期结束,无法再 start() 启动scheduler
                scheduler.shutdown(true)
            }
        } catch (e: Exception) {
            logger.error("关闭所有的任务失败", e)
        }
    }
}

Controller

/**
 * @Author  Anson
 * @Date  2022/1/6 17:33
 * @Version 1.0
 */
@RestController
@RequestMapping(value = ["/v1/quartz-jobs"])
class JobController(
    private val jobService: JobService
) {
    /**
     * 添加新任务
     * @param configDTO
     * @return
     */
    @RequestMapping
    fun addJob(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.addJob(
            configDTO.jobClass,
            configDTO.jobName,
            configDTO.groupName,
            configDTO.cronExpression,
            configDTO.param
        )
        return HttpStatus.OK
    }

    /**
     * 暂停任务
     * @param configDTO
     * @return
     */
    @RequestMapping("/_pause")
    fun pauseJob(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.pauseJob(configDTO.jobName, configDTO.groupName)
        return HttpStatus.OK
    }

    /**
     * 恢复任务
     * @param configDTO
     * @return
     */
    @RequestMapping("/_resume")
    fun resumeJob(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.resumeJob(configDTO.jobName, configDTO.groupName)
        return HttpStatus.OK
    }

    /**
     * 立即运行一次定时任务
     * @param configDTO
     * @return
     */
    @RequestMapping("/_runOnce")
    fun runOnce(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.runOnce(configDTO.jobName, configDTO.groupName)
        return HttpStatus.OK
    }

    /**
     * 更新任务
     * @param configDTO
     * @return
     */
    @PutMapping
    fun updateJob(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.updateJob(configDTO.jobName, configDTO.groupName, configDTO.cronExpression, configDTO.param)
        return HttpStatus.OK
    }

    /**
     * 删除任务
     * @param configDTO
     * @return
     */
    @DeleteMapping
    fun deleteJob(@RequestBody configDTO: QuartzConfigDTO): HttpStatus {
        jobService.deleteJob(configDTO.jobName, configDTO.groupName)
        return HttpStatus.OK
    }

    /**
     * 启动所有任务
     * @return
     */
    @RequestMapping("/_startAll")
    fun startAllJobs(): HttpStatus {
        jobService.startAllJobs()
        return HttpStatus.OK
    }

    /**
     * 暂停所有任务
     * @return
     */
    @RequestMapping("/_pauseAll")
    fun pauseAllJobs(): HttpStatus {
        jobService.pauseAllJobs()
        return HttpStatus.OK
    }

    /**
     * 恢复所有任务
     * @return
     */
    @RequestMapping("/_resumeAll")
    fun resumeAllJobs(): HttpStatus {
        jobService.resumeAllJobs()
        return HttpStatus.OK
    }

    /**
     * 关闭所有任务
     * @return
     */
    @RequestMapping("/_shutdownAll")
    fun shutdownAllJobs(): HttpStatus {
        jobService.shutdownAllJobs()
        return HttpStatus.OK
    }
}

6. 运行

运行程序后,使用postman调用接口添加或执行任务


image.png image.png

相关文章

  • 分布式任务调度平台XXL-JOB搭建教程

    一、使用XXL-JOB的原因 1、 Quartz的不足 Quartz作为开源任务调度中的佼佼者,是任务调度的首选。...

  • Quartz任务调度使用

    继上篇文章记录了XXL-JOB的使用后,但在服务器多节点部署的情况下始终无法生效,可能是因为docker环境导致网...

  • Quartz框架

    Quartz Quartz是一个全功能,开源的任务调度服务。Quartz的核心概念:schedule任务调度,jo...

  • [Spring]支持注解的Spring调度器

    概述 如果想在Spring中使用任务调度功能,除了集成调度框架Quartz这种方式,也可以使用Spring自己的调...

  • spring调度器

    概述 如果想在Spring中使用任务调度功能,除了集成调度框架Quartz这种方式,也可以使用Spring自己的调...

  • Quartz源码解析(1)快速使用

    本章节使用Quartz的基于内存,非集群模式的任务调度StdScheduler讲解

  • Java高级工程师

    Elastic Job 分布式任务调度 Quartz 任务调度 RocketMQ RabbitMQ Acti...

  • 简单了解Quartz

    Quartz是一个任务调度框架,主要用来操作定时任务。Quartz主要使用的模式是工厂模式和Builder模式Qu...

  • Quartz

    Quartz? 任务调度框架“Quartz”是OpenSymphony开源组织在Job scheduling领域又...

  • SpringBoot使用Quartz定时任务———以微信步数为例

    SpringBoot使用Quartz定时任务———以微信步数为例 Quartz:这是一个功能比较强大的的调度器,可...

网友评论

      本文标题:Quartz任务调度使用

      本文链接:https://www.haomeiwen.com/subject/eohdcrtx.html