定时任务框架Quartz的新玩法

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 MongoDB,通用型 2核4GB
简介: 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实现定时任务
999 0
快速上手Quartz实现定时任务
|
8月前
|
存储 开发框架 Java
分布式定时任务框架Quartz总结和实践(1)
Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。
102 0
|
9月前
|
存储 Oracle Java
如何使用Quartz框架来实现任务调度?
如何使用Quartz框架来实现任务调度?
74 0
|
运维 NoSQL 数据库连接
定时任务能力进击!Quartz框架的使用
定时任务能力进击!Quartz框架的使用
|
存储 运维 Java
分布式定时任务-QuartzJava编程
分布式定时任务-QuartzJava编程
分布式定时任务-QuartzJava编程
|
监控 Java 测试技术
听说可以十分钟掌握Spring Boot 集成定时任务、异步调用?
在项目开发中,经常需要定时任务来帮助我们来做一些内容,比如定时发送短信/站内信息、数据汇总统计、业务监控等,所以就要用到我们的定时任务,在Spring Boot中编写定时任务是非常简单的事,下面通过实例介绍如何在Spring Boot中创建定时任务
120 0
听说可以十分钟掌握Spring Boot 集成定时任务、异步调用?
|
存储 Java 数据库连接
Quartz:任务调度实现原理
Quartz:任务调度实现原理
1073 0
Quartz:任务调度实现原理
|
数据可视化 Java 调度
可视化定时任务,quartz集成全解析
在日常的工作中,定时任务也是一个非常常见的需求,可以使用注解实现,但是使用这种方式有几个问题,首先就是如果修改比较麻烦,而且没有提供特定的页面对定时任务进行可视化管理。所以quartz就应运而生。本文将介绍如何实现springboot与quartz的整合。
494 0
可视化定时任务,quartz集成全解析
|
缓存 NoSQL 架构师
Spring Boot从小白到精通(八)熟悉@EnableScheduling,一秒搞定定时任务
今天主要讲解Springboot整合定时任务。在SpringMvc中也会用到很多的定时任务,主要是通过Quartz实现。但是在Spring MVC中使用这些插件相对还是比较麻烦的:要增加一些依赖包,然后加入各种配置等等。Spring Boot相对就简单很多了,现在就来说说Spring Boot 是怎么实现定时任务的。
Spring Boot从小白到精通(八)熟悉@EnableScheduling,一秒搞定定时任务
|
druid Java 数据库
精通SpringBoot——第十篇:使用Quartz实现动态配置定时任务
spring boot 整合quartz实现数据库动态配置定时任务
18737 0