Quartz 架构和单体应用介绍(四)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 阅读完本文大概需要5分钟,本文主要分享内容如下: Quartz 架构介绍 SpringBoot Quartz 应用整合

4.5、动态配置定时任务

从上面的代码中我们可以分析中,定时任务的有三个核心变量,其他的方法都可以封装成公共的。

  • 任务名称:例如myJob
  • 任务执行类:例如TestTask.class
  • 任务调度时间:例如0/5 * * * * ?

基于此规律,我们可以创建一个定时任务实体类,用于保存定时任务相关信息到数据库当中,然后编写一个定时任务工具库,用于创建、更新、删除、暂停任务操作,通过 restful 接口操作将任务存入数据库并管理定时任务!

4.5.1、引入 Jpa 包

<!--jpa 支持-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--mysql 数据源-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

application.properties中加入数据源配置

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

4.5.2、创建任务配置表

CREATE TABLE `tb_job_task` (
  `id` varchar(50)  NOT NULL COMMENT '任务ID',
  `job_name` varchar(100)  DEFAULT NULL COMMENT '任务名称',
  `job_class` varchar(200)  DEFAULT NULL COMMENT '任务执行类',
  `cron_expression` varchar(50)  DEFAULT NULL COMMENT '任务调度时间表达式',
  `status` int(4) DEFAULT NULL COMMENT '任务状态,0:启动,1:暂停,2:停用',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

4.5.3、编写任务实体类

@Entity
@Table(name = "tb_job_task")
public class QuartzBean {
    /**
     * 任务ID
     */
    @Id
    private String id;
    /**
     * 任务名称
     */
    @Column(name = "job_name")
    private String jobName;
    /**
     * 任务执行类
     */
    @Column(name = "job_class")
    private String jobClass;
    /**
     * 任务调度时间表达式
     */
    @Column(name = "cron_expression")
    private String cronExpression;
    /**
     * 任务状态,0:启动,1:暂停,2:停用
     */
    @Column(name = "status")
    private Integer status;
    //get、set...
}

4.5.4、编写任务操作工具类

public class QuartzUtils {
    private static final Logger log = LoggerFactory.getLogger(QuartzUtils.class);
    /**
     * 创建定时任务 定时任务创建之后默认启动状态
     * @param scheduler   调度器
     * @param quartzBean  定时任务信息类
     * @throws Exception
     */
    public static void createScheduleJob(Scheduler scheduler, QuartzBean quartzBean){
        try {
            //获取到定时任务的执行类  必须是类的绝对路径名称
            //定时任务类需要是job类的具体实现 QuartzJobBean是job的抽象类。
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());
            // 构建定时任务信息
            JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(quartzBean.getJobName()).build();
            // 设置定时任务执行方式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
            // 构建触发器trigger
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(quartzBean.getJobName()).withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (ClassNotFoundException e) {
            log.error("定时任务类路径出错:请输入类的绝对路径", e);
        } catch (SchedulerException e) {
            log.error("创建定时任务出错", e);
        }
    }
    /**
     * 根据任务名称暂停定时任务
     * @param scheduler  调度器
     * @param jobName    定时任务名称
     * @throws SchedulerException
     */
    public static void pauseScheduleJob(Scheduler scheduler, String jobName){
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            log.error("暂停定时任务出错", e);
        }
    }
    /**
     * 根据任务名称恢复定时任务
     * @param scheduler  调度器
     * @param jobName    定时任务名称
     * @throws SchedulerException
     */
    public static void resumeScheduleJob(Scheduler scheduler, String jobName) {
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            log.error("暂停定时任务出错", e);
        }
    }
    /**
     * 根据任务名称立即运行一次定时任务
     * @param scheduler     调度器
     * @param jobName       定时任务名称
     * @throws SchedulerException
     */
    public static void runOnce(Scheduler scheduler, String jobName){
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            log.error("运行定时任务出错", e);
        }
    }
    /**
     * 更新定时任务
     * @param scheduler   调度器
     * @param quartzBean  定时任务信息类
     * @throws SchedulerException
     */
    public static void updateScheduleJob(Scheduler scheduler, QuartzBean quartzBean)  {
        try {
            //获取到对应任务的触发器
            TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName());
            //设置定时任务执行方式
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(quartzBean.getCronExpression());
            //重新构建任务的触发器trigger
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
            //重置对应的job
            scheduler.rescheduleJob(triggerKey, trigger);
        } catch (SchedulerException e) {
            log.error("更新定时任务出错", e);
        }
    }
    /**
     * 根据定时任务名称从调度器当中删除定时任务
     * @param scheduler 调度器
     * @param jobName   定时任务名称
     * @throws SchedulerException
     */
    public static void deleteScheduleJob(Scheduler scheduler, String jobName) {
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            log.error("删除定时任务出错", e);
        }
    }
}

4.5.5、编写 Jpa 数据操作服务

public interface QuartzBeanRepository extends JpaRepository<QuartzBean,String> {
    /**
     * 修改任务状态
     * @param id
     * @param status
     */
    @Modifying
    @Transactional
    @Query("update QuartzBean m set m.status = ?2 where m.id =?1")
    void updateState(String id, Integer status);
    /**
     * 修改任务调度时间
     * @param id
     * @param cronExpression
     */
    @Modifying
    @Transactional
    @Query("update QuartzBean m set m.cronExpression = ?2 where m.id =?1")
    void updateCron(String id, String cronExpression);
}

4.5.6、编写controller服务

@RestController
@RequestMapping("/quartz")
public class QuartzController {
    private static final Logger log = LoggerFactory.getLogger(QuartzController.class);
    @Autowired
    private Scheduler scheduler;
    @Autowired
    private QuartzBeanRepository repository;
    /**
     * 创建任务
     * @param quartzBean
     */
    @RequestMapping("/createJob")
    public HttpStatus createJob(@RequestBody  QuartzBean quartzBean)  {
        log.info("=========开始创建任务=========");
        QuartzUtils.createScheduleJob(scheduler,quartzBean);
        repository.save(quartzBean.setId(UUID.randomUUID().toString()).setStatus(0));
        log.info("=========创建任务成功,信息:{}", JSON.toJSONString(quartzBean));
        return HttpStatus.OK;
    }
    /**
     * 暂停任务
     * @param quartzBean
     */
    @RequestMapping("/pauseJob")
    public HttpStatus pauseJob(@RequestBody QuartzBean quartzBean) {
        log.info("=========开始暂停任务,请求参数:{}=========", JSON.toJSONString(quartzBean));
        QuartzUtils.pauseScheduleJob(scheduler, quartzBean.getJobName());
        repository.updateState(quartzBean.getId(), 1);
        log.info("=========暂停任务成功=========");
        return HttpStatus.OK;
    }
    /**
     * 立即运行一次定时任务
     * @param quartzBean
     */
    @RequestMapping("/runOnce")
    public HttpStatus runOnce(@RequestBody QuartzBean quartzBean) {
        log.info("=========立即运行一次定时任务,请求参数:{}", JSON.toJSONString(quartzBean));
        QuartzUtils.runOnce(scheduler,quartzBean.getJobName());
        log.info("=========立即运行一次定时任务成功=========");
        return HttpStatus.OK;
    }
    /**
     * 恢复定时任务
     * @param quartzBean
     */
    @RequestMapping("/resume")
    public HttpStatus resume(@RequestBody QuartzBean quartzBean) {
        log.info("=========恢复定时任务,请求参数:{}", JSON.toJSONString(quartzBean));
        QuartzUtils.resumeScheduleJob(scheduler,quartzBean.getJobName());
        repository.updateState(quartzBean.getId(), 0);
        log.info("=========恢复定时任务成功=========");
        return HttpStatus.OK;
    }
    /**
     * 更新定时任务
     * @param quartzBean
     */
    @RequestMapping("/update")
    public HttpStatus update(@RequestBody QuartzBean quartzBean)  {
        log.info("=========更新定时任务,请求参数:{}", JSON.toJSONString(quartzBean));
        QuartzUtils.updateScheduleJob(scheduler,quartzBean);
        repository.updateCron(quartzBean.getId(), quartzBean.getCronExpression());
        log.info("=========更新定时任务成功=========");
        return HttpStatus.OK;
    }
    /**
     * 删除定时任务
     * @param quartzBean
     */
    @RequestMapping("/delete")
    public HttpStatus delete(@RequestBody QuartzBean quartzBean)  {
        log.info("=========删除定时任务,请求参数:{}", JSON.toJSONString(quartzBean));
        QuartzUtils.deleteScheduleJob(scheduler,quartzBean.getJobName());
        repository.updateState(quartzBean.getId(), 2);
        log.info("=========删除定时任务成功=========");
        return HttpStatus.OK;
    }
}



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
24天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
40 1
服务架构的演进:从单体到微服务的探索之旅
|
27天前
|
监控 Go API
Go语言在微服务架构中的应用实践
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出,成为构建微服务的理想选择。本文将探讨Go语言在微服务架构中的应用实践,包括Go语言的特性如何适应微服务架构的需求,以及在实际开发中如何利用Go语言的特性来提高服务的性能和可维护性。我们将通过一个具体的案例分析,展示Go语言在微服务开发中的优势,并讨论在实际应用中可能遇到的挑战和解决方案。
|
27天前
|
网络协议 数据挖掘 5G
适用于金融和交易应用的低延迟网络:技术、架构与应用
适用于金融和交易应用的低延迟网络:技术、架构与应用
52 5
|
28天前
|
Go 数据处理 API
Go语言在微服务架构中的应用与优势
本文摘要采用问答形式,以期提供更直接的信息获取方式。 Q1: 为什么选择Go语言进行微服务开发? A1: Go语言的并发模型、简洁的语法和高效的编译速度使其成为微服务架构的理想选择。 Q2: Go语言在微服务架构中有哪些优势? A2: 主要优势包括高性能、高并发处理能力、简洁的代码和强大的标准库。 Q3: 文章将如何展示Go语言在微服务中的应用? A3: 通过对比其他语言和展示Go语言在实际项目中的应用案例,来说明其在微服务架构中的优势。
|
25天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
25天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
医疗行业的语音识别技术解析:AI多模态能力平台的应用与架构
AI多模态能力平台通过语音识别技术,实现实时转录医患对话,自动生成结构化数据,提高医疗效率。平台具备强大的环境降噪、语音分离及自然语言处理能力,支持与医院系统无缝集成,广泛应用于门诊记录、多学科会诊和急诊场景,显著提升工作效率和数据准确性。
|
14天前
|
监控 持续交付 API
深入理解微服务架构及其在现代软件开发中的应用
深入理解微服务架构及其在现代软件开发中的应用
21 0
|
25天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
6天前
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。