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

简介: 阅读完本文大概需要5分钟,本文主要分享内容如下: Quartz 架构介绍 SpringBoot Quartz 应用整合

3.1、Job

打开Job源码,里面其实就是一个包含执行方法void execute(JobExecutionContext context)的接口,开发者只需实现接口来定义具体任务即可!

public interface Job {
    void execute(JobExecutionContext context) throws JobExecutionException;
}

JobExecutionContext 类封装了获取上下文的各种信息,Job运行时的信息也保存在 JobDataMap 实例中!

例如,我想要获取在上文初始化时使用到的usingJobData("jobData", "test")参数,可以通过如下方式进行获取!

@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
    //从context中获取instName,groupName以及dataMap
    String jobName = context.getJobDetail().getKey().getName();
    String groupName = context.getJobDetail().getKey().getGroup();
    JobDataMap dataMap = context.getJobDetail().getJobDataMap();
    //从dataMap中获取myDescription,myValue以及myArray
    String value = dataMap.getString("jobData");
    System.out.println("jobName:" + jobName + ",groupName:" + groupName + ",jobData:" + value);
}

输出结果:

jobName:myJob,groupName:myJobGroup,jobData:test

3.2、Trigger

Trigger主要用于描述Job执行的时间触发规则,最常用的有SimpleTriggerCronTrigger两个实现类型。

  • SimpleTrigger:主要处理一些简单的调度规则,例如触发一次或者以固定时间间隔周期执行
  • CronTrigger:调度处理更加灵活,可以通过Cron表达式定义出各种复杂时间规则的调度方案,例如每早晨9:00执行,周一、周三、周五下午5:00执行等;
3.2.1、SimpleTrigger

SimpleTrigger实现每2秒钟执行一次任务为例,代码如下:

public static void main(String[] args) throws SchedulerException {
    //构建一个JobDetail实例...
    // 构建一个Trigger,指定Trigger名称和组,规定该Job立即执行,且两秒钟重复执行一次
    SimpleTrigger trigger = TriggerBuilder.newTrigger()
            .startNow() // 执行的时机,立即执行
            .withIdentity("myTrigger", "myTriggerGroup") // 不是必须的
            .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                    .withIntervalInSeconds(2).repeatForever()).build();
    // 让scheduler开始调度这个job, 按trigger指定的计划
    scheduler.scheduleJob(job, trigger);
}

运行结果:

2020-12-03 16:55:53
2020-12-03 16:55:55
2020-12-03 16:55:57
......

其中最关键的就是withSchedule()这个方法,通过SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()来构建了一个简单的SimpleTrigger类型的任务调度规则,从而实现任务调度!

3.2.2、CronTrigger

如开始介绍的例子一样,里面使用正是CronTrigger类型的调度规则!

public static void main(String[] args) throws SchedulerException {
    //构建一个JobDetail实例...
    // 新建一个Trigger, 表示JobDetail的调度计划, 这里的cron表达式是 每5秒执行一次
    Trigger trigger = TriggerBuilder.newTrigger()
            .withIdentity("myTrigger", "myTriggerGroup")
            .startNow() // 立即执行
            .withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
            .build();
    // 让scheduler开始调度这个job, 按trigger指定的计划
    scheduler.scheduleJob(job, trigger);
}

运行结果:

2020-12-03 17:09:10
2020-12-03 17:09:15
2020-12-03 17:09:20
......

CronTrigger相比SimpleTrigger,在配置调度规则方面,使用cron表达式更加灵活!

3.2.3、Cron 表达式详解

Quartz 的 Cron 表达式,具体配置规则可以参考如下:

.---------------------- seconds(0 - 59)
|  .------------------- minute (0 - 59)
|  |  .---------------- hour (0 - 23)
|  |  |  .------------- day of month (1 - 31)
|  |  |  |  .---------- month (1 - 12)
|  |  |  |  |  .------- Day-of-Week (1 - 7) 
|  |  |  |  |  |  .---- year (1970 - 2099) ...
|  |  |  |  |  |  |
*  *  *  *  *  ?  *

具体样例如下:

82.jpg

在 cron 表达式中不区分大小写,更多配置和使用操作可以参考这里。

还可以在线解析cron表达式进行测试。

83.jpg

3.3、监听器(选用)

quartz 除了提供能正常调度任务的功能之外,还提供了监听器功能!

所谓监听器,其实你可以把它理解为类似Spring Aop的功能,可以对全局或者局部实现监听!

监听器应用,在实际项目中并不常用,但是在某些业务场景下,可以发挥一定的作用,例如:你想在任务处理完成之后,去发送邮件或者发短信进行通知,但是你又不想改以前的代码,这个时候就可以在监听器里面完成改项任务!

quartz 监听器主要分三大类:

  • SchedulerListener:任务调度监听器
  • TriggerListener:任务触发监听器
  • JobListener:任务执行监听器
3.3.1、SchedulerListener

SchedulerListener监听器,主要对任务调度Scheduler生命周期中关键节点进行监听,它只能全局进行监听,简单示例如下:

public class SimpleSchedulerListener implements SchedulerListener {
    @Override
    public void jobScheduled(Trigger trigger) {
        System.out.println("任务被部署时被执行");
    }
    @Override
    public void jobUnscheduled(TriggerKey triggerKey) {
        System.out.println("任务被卸载时被执行");
    }
    @Override
    public void triggerFinalized(Trigger trigger) {
        System.out.println("任务完成了它的使命,光荣退休时被执行");
    }
    @Override
    public void triggerPaused(TriggerKey triggerKey) {
        System.out.println(triggerKey + "(一个触发器)被暂停时被执行");
    }
    @Override
    public void triggersPaused(String triggerGroup) {
        System.out.println(triggerGroup + "所在组的全部触发器被停止时被执行");
    }
    @Override
    public void triggerResumed(TriggerKey triggerKey) {
        System.out.println(triggerKey + "(一个触发器)被恢复时被执行");
    }
    @Override
    public void triggersResumed(String triggerGroup) {
        System.out.println(triggerGroup + "所在组的全部触发器被回复时被执行");
    }
    @Override
    public void jobAdded(JobDetail jobDetail) {
        System.out.println("一个JobDetail被动态添加进来");
    }
    @Override
    public void jobDeleted(JobKey jobKey) {
        System.out.println(jobKey + "被删除时被执行");
    }
    @Override
    public void jobPaused(JobKey jobKey) {
        System.out.println(jobKey + "被暂停时被执行");
    }
    @Override
    public void jobsPaused(String jobGroup) {
        System.out.println(jobGroup + "(一组任务)被暂停时被执行");
    }
    @Override
    public void jobResumed(JobKey jobKey) {
        System.out.println(jobKey + "被恢复时被执行");
    }
    @Override
    public void jobsResumed(String jobGroup) {
        System.out.println(jobGroup + "(一组任务)被恢复时被执行");
    }
    @Override
    public void schedulerError(String msg, SchedulerException cause) {
        System.out.println("出现异常" + msg + "时被执行");
        cause.printStackTrace();
    }
    @Override
    public void schedulerInStandbyMode() {
        System.out.println("scheduler被设为standBy等候模式时被执行");
    }
    @Override
    public void schedulerStarted() {
        System.out.println("scheduler启动时被执行");
    }
    @Override
    public void schedulerStarting() {
        System.out.println("scheduler正在启动时被执行");
    }
    @Override
    public void schedulerShutdown() {
        System.out.println("scheduler关闭时被执行");
    }
    @Override
    public void schedulerShuttingdown() {
        System.out.println("scheduler正在关闭时被执行");
    }
    @Override
    public void schedulingDataCleared() {
        System.out.println("scheduler中所有数据包括jobs, triggers和calendars都被清空时被执行");
    }
}

需要在任务调度器启动前,将SimpleSchedulerListener注册到Scheduler容器中!

// 创建一个Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//添加SchedulerListener监听器
scheduler.getListenerManager().addSchedulerListener(new SimpleSchedulerListener());
// 启动Scheduler
scheduler.start();

运行main方法,输出结果如下:

scheduler正在启动时被执行
scheduler启动时被执行
一个JobDetail被动态添加进来
任务被部署时被执行
2020-12-10 17:27:10
....
相关文章
|
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 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。