定时任务框架Quartz的新玩法

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介: Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。作为企业级别的定时任务调度,Quartz不仅仅拥有强大的调度功能,也支持各种灵活的应用方式,并同时支持分布式和集群能力。 ## 基本使用 Quartz的使用非常简单,首先在POM里面加入引用 ```xml org.quartz-scheduler quartz

Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现。作为企业级别的定时任务调度,Quartz不仅仅拥有强大的调度功能,也支持各种灵活的应用方式,并同时支持分布式和集群能力。

基本使用

Quartz的使用非常简单,首先在POM里面加入引用

<!-- Quartz -->
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz-jobs</artifactId>
    <version>2.2.1</version>
</dependency>

然后在项目初始化的时候启动它

Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();

我们再定义一下定时任务要做啥

public class MyJob implements org.quartz.Job {

      public MyJob() {
      }

      public void execute(JobExecutionContext context) throws JobExecutionException {
          System.err.println("Hello World!  MyJob is executing.");
      }
  }

最后我们就可以增加一个定时任务了

 // 定义一个要执行的Job
  JobDetail job = newJob(MyJob.class)
      .withIdentity("job1", "group1")
      .build();
  // 定义一个间隔40秒运行的Trigger
  Trigger trigger = newTrigger()
      .withIdentity("trigger1", "group1")
      .startNow()
      .withSchedule(simpleSchedule()
              .withIntervalInSeconds(40)
              .repeatForever())
      .build();
  // 告诉Quartz去用trigger安排启动job
  scheduler.scheduleJob(job, trigger);

是不是很简单,其实还有很多用法可以直接取官网上看查阅一下文档,就可以快速实现你的功能了。
http://www.quartz-scheduler.org/documentation/quartz-2.2.x/quick-start.html

提高篇

Quartz在启动过程中会默认读取classpath下的quartz.preperties文件完成一些初始化工作。在这里我们主要谈的是org.quartz.jobStore.class这个配置项。

Quartz官方支持三种数据存储方式

  1. RAMJobStore

    RAMJobStore是默认的数据存储方式,其把数据存在本地内存中,官方宣称这是最有效率的方式(在本地内存当然快啦)。但是在宕机或者重启的时候数据就会丢失。
    //配置方式
    org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
  2. JDBCJobStore

    JDBCJobStore终于把数据给持久化起来了,这个也是使用最广泛的数据存储方式。在于Spring集成后都不需要自己再配置一遍数据库连接了。建表脚本在官方包里面可以找到(http://www.quartz-scheduler.org/downloads/)
    //配置方式
    org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
    org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
    org.quartz.jobStore.tablePrefix = QRTZ_
    org.quartz.jobStore.dataSource = myDS
  3. TerracottaJobStore

    在Quartz被Software AG收购后免不了要夹带一些私货。这个就是专门给Terracotta配置的。我也就懒得讲了,大家网上搜搜吧。
    

说了这么多,其实都是Quartz的标准用法。在使用实践中因为各种原因导致没有办法使用官方提供的三种数据存储方式。所以只有自己动手丰衣足食,开辟新的玩法了。

进阶篇 --- MongoDB

在使用的时候我们会发现Quartz的建表脚本和公司idb不怎么兼容,尝试找过DBA,但是他们也不愿意为单独一个项目做特殊处理。这个时候我们就将视线投入到其他存储方式上了,首先祭出的就是MongoDB。

首先在POM里面引入第三方库

<dependency>
   <groupId>com.novemberain</groupId>
   <artifactId>quartz-mongodb</artifactId>
   <version>2.0.0</version>
</dependency>
<dependency>
   <groupId>org.mongodb</groupId>
   <artifactId>mongo-java-driver</artifactId>
   <version>3.2.2</version>
</dependency>

然后就和JDBCJobStore一样,在quartz.preperties中添加链接配置

org.quartz.jobStore.class=com.novemberain.quartz.mongodb.MongoDBJobStore
org.quartz.jobStore.mongoUri=${mongo.hostName}
org.quartz.jobStore.dbName=quartz
org.quartz.jobStore.collectionPrefix=mycol
org.quartz.threadPool.threadCount=1

如果要启动集群模式的话还需要加入下面的配置

org.quartz.scheduler.instanceName = MyClusteredScheduler
org.quartz.scheduler.instanceId = AUTO
org.quartz.jobStore.isClustered = true

进阶篇 --- Redis

还有一种情况下你会发现没有MongoDB可以使用。环绕四周,还有Redis在旁边。看看内存刑的KV Strore,想想它也可以被持久化到磁盘,于是咬咬牙也就用上了。不过遗憾的是受限于Redis,Quartz不能全功能发挥出来。主要的限制有下面几点

  1. 只支持SimpleTrigger和CronTrigger
  2. 对GroupMatcher来说,只支持StringOperatorName.EQUALS操作
  3. org.quartz.scheduler.instanceName是不支持的,所以你得自己去维护trigger_group_name:trigger_name和job_group_name:job_name
  4. 没有办法使用transaction
  5. JobDataMap的内容是作为String存储和返回
  6. 定时任务没有优先级概念,只在设定的时间内启动

不过瑕不掩瑜(其实是我们也用不上这些高级功能),我们还是可以克服困难愉快的用上Quartz的。首先还是要引入三方包

<dependency>
   <groupId>net.joelinn</groupId>
   <artifactId>quartz-redis-jobstore</artifactId>
   <version>1.1.3</version>
</dependency>

<!-- Redis -->
<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.9.0</version>
</dependency>

其次还是配置一下quartz.preperties

org.quartz.jobStore.class = net.joelinn.quartz.jobstore.RedisJobStore
org.quartz.jobStore.host = ${redis.hostName}
org.quartz.jobStore.password = ${redis.password}
org.quartz.jobStore.port = ${redis.port}
org.quartz.jobStore.database: ${redis.database.quartz}

最后别忘了配置你的Jedis

   <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
       <property name="maxTotal" value="${redis.pool.maxTotal}"></property>
       <property name="maxIdle" value="${redis.pool.maxIdle}"></property>
       <property name="minIdle" value="${redis.pool.minIdle}"></property>
       <property name="maxWaitMillis" value="${redis.pool.maxWaitMillis}"></property>
       <property name="minEvictableIdleTimeMillis" value="${redis.pool.minEvictableIdleTimeMillis}"></property>
       <property name="numTestsPerEvictionRun" value="${redis.pool.numTestsPerEvictionRun}"></property>
       <property name="timeBetweenEvictionRunsMillis" value="${redis.pool.timeBetweenEvictionRunsMillis}"></property>
       <property name="testOnBorrow" value="true"></property>
       <property name="testOnReturn" value="true"></property>
       <property name="testWhileIdle" value="true"></property>
   </bean>

   <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
       <property name="hostName" value="${redis.hostName}"/>
       <property name="port" value="${redis.port}"/>
       <property name="timeout" value="${redis.timeout}"/>
       <property name="database" value="${redis.database.crowd}"/>
       <property name="password" value="${redis.password}"/>
       <property name="usePool" value="true"/>
       <property name="poolConfig" ref="jedisPoolConfig"/>
   </bean>

参考链接

  1. http://www.quartz-scheduler.org/
  2. https://github.com/michaelklishin/quartz-mongodb
  3. https://github.com/jlinn/quartz-redis-jobstore
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
Java 调度 数据库
快速上手Quartz实现定时任务
快速上手Quartz实现定时任务
1070 0
快速上手Quartz实现定时任务
|
5月前
|
运维 监控 Java
SpringBoot-ElasticJob封装快速上手使用(分布式定时器)
SpringBoot-ElasticJob封装快速上手使用(分布式定时器)
|
Java Spring
SpringBoot核心特性——异步任务和定时任务那些事
前言 通常情况下,SpringMVC接收到请求后会将请求具体分发给单个线程进行处理。如果请求处理中涉及到比较耗时的操作,为了能更快地将响应返回给用户,那么就需要将耗时的业务操作交由别的线程进行异步处理,而SpringBoot已经为我们提供了这样的实现。
571 2
SpringBoot核心特性——异步任务和定时任务那些事
|
存储 开发框架 Java
分布式定时任务框架Quartz总结和实践(1)
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。
189 0
|
存储 Oracle Java
如何使用Quartz框架来实现任务调度?
如何使用Quartz框架来实现任务调度?
109 0
|
XML druid 前端开发
【SpringBoot技术指南】「开发实战系列」动态化Quartz任务调度机制+实时推送任务数据到前端
【SpringBoot技术指南】「开发实战系列」动态化Quartz任务调度机制+实时推送任务数据到前端
290 0
【SpringBoot技术指南】「开发实战系列」动态化Quartz任务调度机制+实时推送任务数据到前端
|
运维 NoSQL 数据库连接
定时任务能力进击!Quartz框架的使用
定时任务能力进击!Quartz框架的使用
|
存储 运维 Java
分布式定时任务-QuartzJava编程
分布式定时任务-QuartzJava编程
分布式定时任务-QuartzJava编程
|
开发者 微服务
项目中整合定时任务 | 学习笔记
快速学习 项目中整合定时任务
125 0
|
Java 调度 Spring
SpringBoot 异步任务+定时任务(附源码)
SpringBoot 异步任务+定时任务(附源码)
159 0
SpringBoot 异步任务+定时任务(附源码)
下一篇
无影云桌面