前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >quartz使用案例篇【面试+工作】

quartz使用案例篇【面试+工作】

作者头像
Java帮帮
发布2018-07-26 14:45:13
1.5K0
发布2018-07-26 14:45:13
举报

quartz使用案例篇【面试+工作】

一.Quartz特点

运行环境
  • Quartz 可以运行嵌入在另一个独立式应用程序
  • Quartz 可以在应用程序服务器(或servlet容器)内被实例化,并且参与XA事务
  • Quartz 可以作为一个独立的程序运行(其自己的Java虚拟机内),可以通过RMI使用
  • Quartz 可以被实例化,作为独立的项目集群(负载平衡和故障转移功能),用于作业的执行
作业调度

作业被安排在一个给定的触发时运行。触发器可以使用以下指令的接近任何组合来创建:

  • 在一天中的某个时间(到毫秒)
  • 在一周的某几天
  • 在每月的某一天
  • 在一年中的某些日期
  • 不在注册的日历中列出的特定日期(如商业节假日除外)
  • 重复特定次数
  • 重复进行,直到一个特定的时间/日期
  • 无限重复
  • 重复的延迟时间间隔

作业是由其创建者赋予的名字,也可以组织成命名组。触发器也可以给予名称和放置在组中,以方便地将它们调度内组织。作业可以被添加到所述调度器一次,而是具有多个触发器注册。在企业Java环境中,作业可以执行自己的工作作为分布式(XA)事务的一部分。

作业执行
  • 作业可以实现简单的作业接口,为作业执行工作的任何Java类。
  • Job类的实例可以通过Quartz被实例化,或者通过应用程序框架。
  • 当触发时,调度通知实现JobListener和TriggerListener接口零个或多个Java对象(监听器可以是简单的Java对象,或EJB,JMS或发布者等)。这些监听器在作业已经执行之后通知。
  • 由于作业完成后返回JobCompletionCode,它通知的成功或失败的调度。JobCompletionCode还可以指示的基础上,成功的话就采取行动调度/失败的代码 - 如立即重新执行作业。
作业持久性
  • Quartz的设计包括可被实现以提供的作业存储各种机制一个作业存储接口
  • 通过使用包含的JDBCJobStore,所有的作业和触发器配置为“非挥发性”都存储在通过JDBC关系数据库。
  • 通过使用包含的RAMJobStore,所有的作业和触发器存储在RAM,因此不计划执行仍然存在 - 但这是无需使用外部数据库的优势。
事务
  • 可以参与JTA事务,通过使用JobStoreCMT(JDBCJobStore的子类)。
  • Quartz可以管理JTA事务(开始并提交它们)周围作业的执行,从而使作业执行的工作自动将JTA事务中发生。
集群
  • 故障切换
  • 负载均衡
  • Quartz的内置的群集功能,通过JDBCJobStore(如上所述)依靠数据库持久
  • Terracotta扩展Quartz提供集群功能,而不需要一个支持数据库
监听器和插件
  • 应用程序可以捕捉事件的调度监控或通过实现一个或多个监听器接口控制工作/触发行为。
  • 插件机制,可以用来添加功能,Quartz让作业执行过程中或工作负载和触发定义的历史不受限在一个文件中。
  • 附带了一些“工厂建有”插件和监听器。

二.入门案例

Quartz, 是一个企业级调度工作的框架,帮助Java应用程序到调度工作/任务在指定的日期和时间运行。

本教程教作为一个入门介绍如何开发使用调度工作(在写本教程时使用的最新Quartz 2.2.1 )

1. 下载Quartz

可以从官方网站或Maven中央存储库下载Quartz库文件;

File : quartz.properties

org.quartz.scheduler.instanceName = MyScheduler

org.quartz.threadPool.threadCount = 3

org.quartz.jobStore.class =org.quartz.simpl.RAMJobStore

2. Quartz 作业

Quartz作业定义要运行什么?

File : HelloJob

package cn.com.javahelp.common;

import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;

public class HelloJob implements Job{

public void execute(JobExecutionContext context)

throws JobExecutionException {

System.out.println("Hello Quartz!");

}}

3. Quartz触发器

定义Quartz触发器,当Quartz运行在上面的Quartz作业。

像老版本的Quartz,仍然有两种类型的触发器在Quartz2,但API有些变化:

· SimpleTrigger – 允许设置开始时间,结束时间,重复间隔。

· CronTrigger – 允许UNIX cron表达式来指定日期和时间来运行作业。

SimpleTrigger – 每5秒运行。

Trigger trigger = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName", "group1")

.withSchedule(

SimpleScheduleBuilder.simpleSchedule()

.withIntervalInSeconds(5).repeatForever())

.build();

CronTrigger – 每5秒运行。

Trigger trigger = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

注意 请阅读 官方文档 更多的Quartz2触发器的例子。

4. Scheduler

调度类链接“工作”和“触发器”到一起,并执行它。

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.start();

scheduler.scheduleJob(job, trigger);

5. 完整的例子

Quartz2 两个 SimpleTrigger 和 CronTrigger 完整的例子。

SimpleTrigger的例子 - 每间隔5秒运行。

package cn.com.javahelp.quartz;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.SimpleScheduleBuilder;

import org.quartz.Trigger;

import org.quartz.TriggerBuilder;

import org.quartz.impl.StdSchedulerFactory;

public class SimpleTriggerExample {

public static void main(String[] args) throws Exception {

// Quartz 1.6.3

// JobDetail job = new JobDetail();

// job.setName("dummyJobName");

// job.setJobClass(HelloJob.class);

JobDetail job = JobBuilder.newJob(HelloJob.class)

.withIdentity("dummyJobName", "group1").build();

//Quartz 1.6.3

// SimpleTrigger trigger = new SimpleTrigger();

// trigger.setStartTime(new Date(System.currentTimeMillis() + 1000));

// trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);

// trigger.setRepeatInterval(30000);

// Trigger the job to run on the next round minute

Trigger trigger = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName", "group1")

.withSchedule(

SimpleScheduleBuilder.simpleSchedule()

.withIntervalInSeconds(5).repeatForever())

.build();

// schedule it

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.start();

scheduler.scheduleJob(job, trigger);

}}

CronTrigger例子 - 同样,在每5秒运行作业。

package cn.com.javahelp.quartz;

import org.quartz.CronScheduleBuilder;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.Scheduler;

import org.quartz.Trigger;

import org.quartz.TriggerBuilder;

import org.quartz.impl.StdSchedulerFactory;

public class CronTriggerExample {

public static void main( String[] args ) throws Exception

{

//Quartz 1.6.3

//JobDetail job = new JobDetail();

//job.setName("dummyJobName");

//job.setJobClass(HelloJob.class);

JobDetail job = JobBuilder.newJob(HelloJob.class)

.withIdentity("dummyJobName", "group1").build();

//Quartz 1.6.3

//CronTrigger trigger = new CronTrigger();

//trigger.setName("dummyTriggerName");

//trigger.setCronExpression("0/5 * * * * ?");

Trigger trigger = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

//schedule it

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.start();

scheduler.scheduleJob(job, trigger);

}}

三.作业监听详解

我们将展示/介绍如何创建一个JobListener,跟踪运行工作状态在作业完成等。

P.S 这个例子是Quartz 2.1.5

1. Quartz 作业

作业 - 用于打印一个简单的信息,并抛出一个JobExecutionException进行测试。

File : HelloJob.java

package cn.com.javahelp;

import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;

public class HelloJob implements Job{

public void execute(JobExecutionContext context)

throws JobExecutionException {

System.out.println("Hello Quartz! - by yiibai.com");

//Throw exception for testing

throw new JobExecutionException("Testing Exception");

}

}

2. JobListener

创建一个JobListener,只是实现了JobListener接口,并覆盖所有的接口的方法。

File : HelloJobListener.java

package cn.com.javahelp.quartz.listener;

import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.quartz.JobListener;

public class HelloJobListener implements JobListener {

public static final String LISTENER_NAME = "dummyJobListenerName";

@Override

public String getName() {

return LISTENER_NAME; //must return a name

}

// Run this if job is about to be executed.

@Override

public void jobToBeExecuted(JobExecutionContext context) {

String jobName = context.getJobDetail().getKey().toString();

System.out.println("jobToBeExecuted");

System.out.println("Job : " + jobName + " is going to start...");

}

// No idea when will run this?

@Override

public void jobExecutionVetoed(JobExecutionContext context) {

System.out.println("jobExecutionVetoed");

}

//Run this after job has been executed

@Override

public void jobWasExecuted(JobExecutionContext context,

JobExecutionException jobException) {

System.out.println("jobWasExecuted");

String jobName = context.getJobDetail().getKey().toString();

System.out.println("Job : " + jobName + " is finished...");

if (!jobException.getMessage().equals("")) {

System.out.println("Exception thrown by: " + jobName

+ " Exception: " + jobException.getMessage());

}

}

}

注意: 不知道什么是“jobExecutionVetoed”,并会在何时触发?

3. CronTrigger

例如上面HelloJobListener连接到调度和监控作业的状态。

File : CronTriggerExample.java

package cn.com.javahelp.quartz;

import org.quartz.CronScheduleBuilder;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.JobKey;

import org.quartz.Scheduler;

import org.quartz.Trigger;

import org.quartz.TriggerBuilder;

import org.quartz.impl.StdSchedulerFactory;

import org.quartz.impl.matchers.KeyMatcher;

import cn.com.javahelp.quartz.listener.HelloJobListener;

public class CronTriggerExample {

public static void main( String[] args ) throws Exception

{

JobKey jobKey = new JobKey("dummyJobName", "group1");

JobDetail job = JobBuilder.newJob(HelloJob.class)

.withIdentity(jobKey).build();

Trigger trigger = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

//Listener attached to jobKey

scheduler.getListenerManager().addJobListener(

new HelloJobListener(), KeyMatcher.keyEquals(jobKey)

);

//Listener attached to group named "group 1" only.

//scheduler.getListenerManager().addJobListener(

// new HelloJobListener(), GroupMatcher.jobGroupEquals("group1")

//);

scheduler.start();

scheduler.scheduleJob(job, trigger);

}}

运行CronTriggerExample.java, 这里是输出结果:

jobToBeExecuted

Job : group1.dummyJobName is going to start...

Hello Quartz! - by yiibai.com

jobWasExecuted

Job : group1.dummyJobName is started and finished...

Exception thrown by: group1.dummyJobName Exception: Testing Exception

jobToBeExecuted

Job : group1.dummyJobName is going to start...

Hello Quartz! - by yiibai.com

jobWasExecuted

Job : group1.dummyJobName is started and finished...

Exception thrown by: group1.dummyJobName Exception: Testing Exception

四.执行多作业

在这个例子中,我们将介绍如何通过Quartz API 多个作业。在Quartz调度框架中,每个作业将被连接到一个唯一的触发,并且由调度器运行它。

P.S:在 Quartz 中,一个触发器触发多个作业是不可以的。

1. Quartz APIs

创建3个作业,JobA,JobB和JobC。

package cn.com.javahelp.quartz;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class JobA implements Job {

@Override

public void execute(JobExecutionContext context)

throws JobExecutionException {

System.out.println("Job A is runing //every 5 seconds ");

}

}

package cn.com.javahelp.quartz;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class JobB implements Job {

@Override

public void execute(JobExecutionContext context)

throws JobExecutionException {

System.out.println("Job B is runing");

}

}

package cn.com.javahelp.quartz;

import org.quartz.Job;

import org.quartz.JobExecutionContext;

import org.quartz.JobExecutionException;

public class JobC implements Job {

@Override

public void execute(JobExecutionContext context)

throws JobExecutionException {

System.out.println("Job C is runing");

}

}

使用QuartzAPI声明上述3个作业,分配它们到特定触发器并调度它。

package cn.com.javahelp.quartz;

import org.quartz.CronScheduleBuilder;

import org.quartz.JobBuilder;

import org.quartz.JobDetail;

import org.quartz.JobKey;

import org.quartz.Scheduler;

import org.quartz.Trigger;

import org.quartz.TriggerBuilder;

import org.quartz.impl.StdSchedulerFactory;

public class CronTriggerExample {

public static void main( String[] args ) throws Exception

{

JobKey jobKeyA = new JobKey("jobA", "group1");

JobDetail jobA = JobBuilder.newJob(JobA.class)

.withIdentity(jobKeyA).build();

JobKey jobKeyB = new JobKey("jobB", "group1");

JobDetail jobB = JobBuilder.newJob(JobB.class)

.withIdentity(jobKeyB).build();

JobKey jobKeyC = new JobKey("jobC", "group1");

JobDetail jobC = JobBuilder.newJob(JobC.class)

.withIdentity(jobKeyC).build();

Trigger trigger1 = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName1", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

Trigger trigger2 = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName2", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

Trigger trigger3 = TriggerBuilder

.newTrigger()

.withIdentity("dummyTriggerName3", "group1")

.withSchedule(

CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))

.build();

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

scheduler.start();

scheduler.scheduleJob(jobA, trigger1);

scheduler.scheduleJob(jobB, trigger2);

scheduler.scheduleJob(jobC, trigger3);

}}

输出结果如上:

Job A is runing //every 5 seconds

Job B is runing

Job C is runing

Job A is runing //every 5 seconds

Job B is runing

Job C is runing

五.列出调度所有作业

下面是两个代码片段展示如何列出所有Quartz的作业。Quartz2 API都发生了很大变化,所以语法和Quartz1.x是不同的

1. Quartz 2.2.1 示例

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

for (String groupName : scheduler.getJobGroupNames()) {

for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName))) {

String jobName = jobKey.getName();

String jobGroup = jobKey.getGroup();

//get job's trigger

List<Trigger> triggers = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);

Date nextFireTime = triggers.get(0).getNextFireTime();

System.out.println("[jobName] : " + jobName + " [groupName] : "

+ jobGroup + " - " + nextFireTime);

}

}

2. Quartz 1.8.6 示例

Scheduler scheduler = new StdSchedulerFactory().getScheduler();

//loop all group

for (String groupName : scheduler.getJobGroupNames()) {

//loop all jobs by groupname

for (String jobName : scheduler.getJobNames(groupName)) {

//get job's trigger

Trigger[] triggers = scheduler.getTriggersOfJob(jobName,groupName);

Date nextFireTime = triggers[0].getNextFireTime();

System.out.println("[jobName] : " + jobName + " [groupName] : "

+ groupName + " - " + nextFireTime);

}

}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java帮帮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.Quartz特点
    • 运行环境
      • 作业调度
        • 作业执行
          • 作业持久性
            • 事务
              • 集群
                • 监听器和插件
                • 二.入门案例
                  • 1. 下载Quartz
                    • 2. Quartz 作业
                      • 3. Quartz触发器
                        • 4. Scheduler
                          • 5. 完整的例子
                          • 三.作业监听详解
                            • 1. Quartz 作业
                              • 2. JobListener
                                • 3. CronTrigger
                                • 四.执行多作业
                                  • 1. Quartz APIs
                                  • 五.列出调度所有作业
                                    • 1. Quartz 2.2.1 示例
                                      • 2. Quartz 1.8.6 示例
                                      相关产品与服务
                                      负载均衡
                                      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
                                      领券
                                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档