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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 阅读完本文大概需要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;
    }
}



相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
1月前
|
缓存 Cloud Native 中间件
《聊聊分布式》从单体到分布式:电商系统架构演进之路
本文系统阐述了电商平台从单体到分布式架构的演进历程,剖析了单体架构的局限性与分布式架构的优势,结合淘宝、京东等真实案例,深入探讨了服务拆分、数据库分片、中间件体系等关键技术实践,并总结了渐进式迁移策略与核心经验,为大型应用架构升级提供了全面参考。
|
1月前
|
人工智能 JavaScript 前端开发
GenSX (不一样的AI应用框架)架构学习指南
GenSX 是一个基于 TypeScript 的函数式 AI 工作流框架,以“函数组合替代图编排”为核心理念。它通过纯函数组件、自动追踪与断点恢复等特性,让开发者用自然代码构建可追溯、易测试的 LLM 应用。支持多模型集成与插件化扩展,兼具灵活性与工程化优势。
192 6
|
2月前
|
人工智能 Cloud Native 中间件
划重点|云栖大会「AI 原生应用架构论坛」看点梳理
本场论坛将系统性阐述 AI 原生应用架构的新范式、演进趋势与技术突破,并分享来自真实生产环境下的一线实践经验与思考。
|
2月前
|
机器学习/深度学习 人工智能 vr&ar
H4H:面向AR/VR应用的NPU-CIM异构系统混合卷积-Transformer架构搜索——论文阅读
H4H是一种面向AR/VR应用的混合卷积-Transformer架构,基于NPU-CIM异构系统,通过神经架构搜索实现高效模型设计。该架构结合卷积神经网络(CNN)的局部特征提取与视觉Transformer(ViT)的全局信息处理能力,提升模型性能与效率。通过两阶段增量训练策略,缓解混合模型训练中的梯度冲突问题,并利用异构计算资源优化推理延迟与能耗。实验表明,H4H在相同准确率下显著降低延迟和功耗,为AR/VR设备上的边缘AI推理提供了高效解决方案。
399 0
|
1月前
|
机器学习/深度学习 自然语言处理 算法
48_动态架构模型:NAS在LLM中的应用
大型语言模型(LLM)在自然语言处理领域的突破性进展,很大程度上归功于其庞大的参数量和复杂的网络架构。然而,随着模型规模的不断增长,计算资源消耗、推理延迟和部署成本等问题日益凸显。如何在保持模型性能的同时,优化模型架构以提高效率,成为2025年大模型研究的核心方向之一。神经架构搜索(Neural Architecture Search, NAS)作为一种自动化的网络设计方法,正在为这一挑战提供创新性解决方案。本文将深入探讨NAS技术如何应用于LLM的架构优化,特别是在层数与维度调整方面的最新进展,并通过代码实现展示简单的NAS实验。
|
3月前
|
Web App开发 Linux 虚拟化
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
237 0
Omnissa Horizon 8 2506 (8.16) - 虚拟桌面基础架构 (VDI) 和应用软件
|
3月前
|
机器学习/深度学习 数据采集 存储
技术赋能下的能源智慧管理:MyEMS 开源系统的架构创新与应用深化
在全球能源转型与“双碳”战略推动下,MyEMS作为基于Python的开源能源管理系统,凭借模块化架构与AI技术,助力重点用能单位实现数字化、智能化能源管理。系统支持多源数据采集、智能分析、设备数字孪生与自适应优化控制,全面满足国家级能耗监测要求,并已在制造、数据中心、公共建筑等领域成功应用,助力节能降碳,推动绿色可持续发展。
115 0
|
1月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路

热门文章

最新文章

下一篇
oss云网关配置