`
1308706231
  • 浏览: 4581 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

quartz集群

 
阅读更多
Quartz体系结构
Quartz对任务调度的领域问题进行了高度的抽象,提出了调度器、任务和触发器这3个核心的概念,并在org.quartz通过接口和类对重要的这些核心概念进行描述:
●Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息。Job运行时的信息保存在JobDataMap实例中。
●JobDetail:Quartz在每次执行Job时,都重新创建一个Job实例,所以它不直接接受一个Job的实例,相反它接收一个Job实现类,以便运行时通过newInstance()的反射机制实例化Job。因此需要通过一个类来描述Job的实现类及其它相关的静态信息,如Job名字、描述、关联监听器等信息,JobDetail承担了这一角色。
通过该类的构造函数可以更具体地了解它的功用:JobDetail(java.lang.String name, java.lang.String group, java.lang.Class jobClass),该构造函数要求指定Job的实现类,以及任务在Scheduler中的组名和Job名称。
●Trigger:是一个类,描述触发Job执行的时间触发规则。主要有SimpleTrigger和CronTrigger这两个子类。当仅需触发一次或者以固定时间间隔周期执行,SimpleTrigger是最适合的选择;而CronTrigger则可以通过Cron表达式定义出各种复杂时间规则的调度方案:如每早晨9:00执行,周一、周三、周五下午5:00执行等。
●Calendar:org.quartz.Calendar和java.util.Calendar不同,它是一些日历特定时间点的集合(可以简单地将org.quartz.Calendar看作java.util.Calendar的集合——java.util.Calendar代表一个日历时间点,无特殊说明后面的Calendar即指org.quartz.Calendar)。一个Trigger可以和多个Calendar关联,以便排除或包含某些时间点。假设,我们安排每周星期一早上10:00执行任务,但是如果碰到法定的节日,任务则不执行,这时就需要在Trigger触发机制的基础上使用Calendar进行定点排除。针对不同时间段类型,Quartz在org.quartz.impl.calendar包下提供了若干个Calendar的实现类,如AnnualCalendar、MonthlyCalendar、WeeklyCalendar分别针对每年、每月和每周进行定义。
●Scheduler:代表一个Quartz的独立运行容器,Trigger和JobDetail可以注册到Scheduler中,两者在Scheduler中拥有各自的组及名称,组及名称是Scheduler查找定位容器中某一对象的依据,Trigger的组及名称必须唯一,JobDetail的组和名称也必须唯一(但可以和Trigger的组和名称相同,因为它们是不同类型的)。Scheduler定义了多个接口方法,允许外部通过组及名称访问和控制容器中Trigger和JobDetail。
Scheduler可以将Trigger绑定到某一JobDetail中,这样当Trigger触发时,对应的Job就被执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。可以通过SchedulerFactory创建一个Scheduler实例。Scheduler拥有一个SchedulerContext,它类似于ServletContext,保存着Scheduler上下文信息,Job和Trigger都可以访问SchedulerContext内的信息。SchedulerContext内部通过一个Map,以键值对的方式维护这些上下文数据,SchedulerContext为保存和获取数据提供了多个put()和getXxx()的方法。可以通过Scheduler# getContext()获取对应的SchedulerContext实例。
●ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提高运行效率。
Quartz数据库表
   因为Quartz集群依赖于数据库,所以必须首先创建Quartz数据库表,Quartz包括了所有被支持的数据库平台的SQL脚本。在 quartz-2.2.1-distribution\quartz-2.2.1\docs\dbTables 目录下找到那些SQL脚本选择相应数据库执行,mysql脚本执行以后如下图:




表名 描述
QRTZ_BLOG_TRIGGERS Trigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型,JobStore 并不知道如何存储实例的时候)
QRTZ_CALENDARS 以Blob类型存储Quartz的Calendar信息
QRTZ_CRON_TRIGGERS 存储Cron Trigger,包括Cron表达式和时区信息
QRTZ_FIRED_TRIGGERS 存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息
QRTZ_JOB_DETAILS 存储每一个已配置的Job的详细信息
QRTZ_LOCKS 存储程序的非观锁的信息(假如使用了悲观锁)
QRTZ_PAUSED_TRIGGER_GRPS 存储已暂停的Trigger组的信息
QRTZ_SCHEDULER_STATE 存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
QRTZ_JOB_LISTENERS 存储有关已配置的 JobListener的信息
QRTZ_SIMPLE_TRIGGERS 存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
QRTZ_SIMPROP_TRIGGERS  
QRTZ_TRIGGERS 存储已配置的 Trigger的信息
 
JOB类实现
import java.util.Date;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SimpleJob implements Job {

    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleJob.class);

    public SimpleJob() {
    }

    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.err.println("Hello world");
    }
}
 
JOB配置文件XML
注:2.2.1版本给定例子是version=1.8如引用必须修改为2.0 
jobXML
<?xml version="1.0" encoding="UTF-8"?>
<job-scheduling-data xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                      xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd"
                      version="2.0">
      
       <schedule>
           <job>
               <name>SimpleJob</name>
               <group>SimpleJobGroup</group>
               <description>djob</description>
               <job-class>com.fangdd.channel.SimpleJob</job-class>
               <durability>true</durability>
               <recover>false</recover>
           </job>
           <trigger>
               <cron>
                   <name>SimpleJobCronGroup</name>
                   <group>SimpleGroupCron</group>
                   <job-name>SimpleJob</job-name>
                   <job-group>SimpleJobGroup</job-group>
                   <misfire-instruction>MISFIRE_INSTRUCTION_FIRE_ONCE_NOW</misfire-instruction>
                   <cron-expression>0/10 * * * * ?</cron-expression>
               </cron>
           </trigger>
       </schedule>
</job-scheduling-data>
说明:
<job>
    name: 集群中job的名字,该名字用户自己可以随意定制,无强行要求。
   group: 集群中job的所属组的名字,该名字用户自己随意定制,无强行要求。
   job-class:集群中job实现类的完全包名,quartz就是根据这个路径到classpath找到该job类的。
  durability:是否持久化,把该属性设置为true,quartz会把job持久化到数据库中
<trigger>
    name:  trigger的名字,该名字用户自己可以随意定制,无强行要求
    group:  trigger所属组的名字,该名字用户自己随意定制,无强行要求
   job_name:    对应Job name
   job_group:     对应job group
  cron-expression:   触发器类型,使用cron表达式
   misfire-instruction:如果设置MISFIRE_INSTRUCTION_DO_NOTHING,则不对misfire的任务做特殊处理,只从当前时间之后的下一次正常调度时间开始执行
Quartz配置文件说明
默认文件名称quartz.properties,通过设置"org.quartz.jobStore.isClustered"属性为"true"来激活集群特性。在集群中的每一个实例都必须有一个唯一的"instance id" ("org.quartz.scheduler.instanceId" 属性), 但是应该有相同的"scheduler instance name" ("org.quartz.scheduler.instanceName"),也就是说集群中的每一个实例都必须使用相同的quartz.properties 配置文件。
除了以下几种例外,配置文件的内容其他都必须相同:
a.不同的线程池大小。
b.不同的"org.quartz.scheduler.instanceId"属性值(这个可以很容易做到,设定为"AUTO"即可)。
注意:
1、永远不要在不同的机器上运行集群,除非他们的时钟是使用某种形式的同步服务(守护)非常有规律的运行(时钟必须在一分一秒内)来达到同步。
2、永远不要触发一个非集群的实例,如果其他的实例正在同一个数据库表上运行。你将使你的数据严重腐蚀,出现非预期行为。
配置文件quartz
#============================================================================
# Configure Main Scheduler Properties 
#在集群中每个实例都必须有一个唯一的instanceId,但是应该有一个相同的instanceName
#============================================================================

org.quartz.scheduler.instanceName: TestScheduler
org.quartz.scheduler.instanceId: AUTO

org.quartz.scheduler.skipUpdateCheck: true

#============================================================================
# Configure ThreadPool 
#定义线程池,SimpleThreadPool这个线程池只是简单地在它的池中保持固定数量的线程,不增长也不缩小。
#但是它非常健壮且经过良好的测试,差不多每个Quartz用户都使用这个池。
#threadCount最多3个
#============================================================================

org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 3
org.quartz.threadPool.threadPriority: 5

#============================================================================
# Configure JobStore 
#配置数据存储的方式
#一个触发器被认定为“misfired”之前,调度器所能容忍的毫秒数
#============================================================================

org.quartz.jobStore.misfireThreshold: 60000
#所有的Quartz数据,例如Job和Trigger的细节信息被存储在内存(数据库)
#配置事务。JobStoreTX来让Quartz帮你管理事务(这是最普遍的选择)。
#如果想让Quartz同其他的事务协同工作(例如:J2EE应用服务器中的事务),那么你需要使用JobStoreCMT,这样,Quartz就会让应用服务器容器来管理事务
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
org.quartz.jobStore.class: org.quartz.impl.jdbcjobstore.JobStoreTX
#DriverDelegate负责做指定数据库的所有JDBC工作.  如果数据库没有其他指定的代理,那么就试用代理StdJDBCDelegate
org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate
#为了指示JDBCJobStore所有的JobDataMaps中的值都是字符串,
#并且能以“名字-值”对的方式存储而不是以复杂对象的序列化形式存储在BLOB字段中,应设置值为”true”(这是缺省的方式)
org.quartz.jobStore.useProperties: false
#配置数据源源的名数、据库表前前缀
org.quartz.jobStore.dataSource: myDS
org.quartz.jobStore.tablePrefix: QRTZ_
#配置数据源源的名数、据库表前前缀
org.quartz.jobStore.isClustered: true

#============================================================================
# Configure Datasources 
#============================================================================

org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.myDS.URL = jdbc\:mysql\://localhost\:3306/quartz_tables?useUnicode\=true&characterEncoding\=utf-8
org.quartz.dataSource.myDS.user = root
org.quartz.dataSource.myDS.password = 123456
#如果Scheduler非常忙(比如,执行的任务数量差不多和线程池的数量相同,那么你需要正确地配置DataSource的连接数量为线程池数量+1)
org.quartz.dataSource.myDS.maxConnections = 10

#============================================================================
# Configure Plugins
#============================================================================

org.quartz.plugin.triggHistory.class: org.quartz.plugins.history.LoggingJobHistoryPlugin
#1.8以前org.quartz.plugin.jobInitializer,1.8以后org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.class: org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
org.quartz.plugin.jobInitializer.fileNames: quartz_job.xml
org.quartz.plugin.jobInitializer.failOnFileNotFound: true
org.quartz.plugin.jobInitializer.scanInterval: 120
org.quartz.plugin.jobInitializer.wrapInUserTransaction: false
Web文件中加载quartz两种方式:
 通过servlet
servlet标签
<servlet>
         <servlet-name>QuartzInitializer</servlet-name>
         <servlet-class>org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
         <load-on-startup>1</load-on-startup>
         <init-param>
             <param-name>config-file</param-name>
             <param-value>quartz.properties</param-value>
         </init-param>
       <init-param>
             <param-name>shutdown-on-unload</param-name>
             <param-value>true</param-value>
         </init-param>
         <init-param> 
             <param-name>wait-on-shutdown</param-name> 
             <param-value>true</param-value> 
         </init-param> 
         <init-param> 
             <param-name>start-scheduler-on-load</param-name> 
             <param-value>true</param-value> 
         </init-param>
        
     </servlet>
    通过listener
listener标签
<context-param>
     <param-name>config-file</param-name>
     <param-value>quartz.properties</param-value>
     </context-param>
     <context-param>
     <param-name>shutdown-on-unload</param-name>
     <param-value>true</param-value>
     </context-param>
     <context-param>
     <param-name>start-scheduler-on-load</param-name>
     <param-value>true</param-value>
     </context-param>
    
     <listener>
     <listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
     </listener>
注:自己通过实现ServletContextListener也可以
  public void contextDestroyed(ServletContextEvent servletContextEvent) {
        try {
            StdSchedulerFactory.getDefaultScheduler().shutdown();
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        // TODO Auto-generated method stub
    }
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        try {
            StdSchedulerFactory.getDefaultScheduler().start();
          
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
具体例子实现jfinal1.8+quartzy2.2.1
  • 大小: 82 KB
分享到:
评论

相关推荐

    quartz 集群解决方法

    Quartz集群需要将所有调度信息(如Job、Trigger)存储在一个共享的持久化存储中,以便所有集群节点都能访问。这通常通过实现`ISchedulerFactory`接口的`StdSchedulerFactory`类和数据库连接来完成。数据库可以选择...

    spring quartz集群配置

    在Quartz集群中,多个Quartz服务器共享同一个“作业存储”(Job Store),这个存储可以是关系数据库或者分布式的存储系统。当一个服务器触发一个作业时,其他服务器会看到这个作业已经被触发,因此不会重复执行。这...

    spring boot quartz集群实现

    一个基于springboot的quartz集群dome。 向http://localhost:9090/job/addjob注入3个参数 类名:(及时定时任务的类如:com.ybjdw.site.job.NewJob) 组名:随意 定时启动方法:如“0/3 * * * * ?”(每3秒启动一次...

    quartz集群Sql大放送

    Quartz集群是为了实现高可用性和负载均衡,当一个节点故障时,其他节点能够接管任务,保证服务不中断。 在Quartz集群中,数据库扮演了至关重要的角色,因为它存储了所有关于作业和触发器的信息。集群中的各个节点...

    SSH框架+Quartz集群

    在压缩包文件"oa_ssh"中,可能包含了项目的所有源代码、配置文件、数据库脚本等资源,开发者可以通过这些文件了解和学习SSH框架与Quartz集群的整合实现,以及RABC权限管理的具体细节。通过研究和实践,可以深入理解...

    quartz集群完整应用实例

    本篇将基于"quartz集群完整应用实例"来深入探讨Quartz的集群配置与实现。 Quartz的核心概念包括Job(任务)、Trigger(触发器)和Scheduler(调度器)。Job是执行的具体任务,Trigger定义了任务何时运行,而...

    spring quartz 集群模式

    Quartz集群通过共享内存中的状态来实现任务的分配和执行,当一个节点失败时,其他节点能够接管未完成的任务。实现Quartz集群,需要配置多个Quartz服务器共享同一份数据库存储,用于保存Job、Trigger以及运行状态等...

    quartz集群各数据库中对应的表机构

    在构建Quartz集群时,为了实现高可用性和任务的分布式处理,需要在多个节点之间共享状态信息,这就涉及到数据库的支持。数据库在这里起到了存储作业和触发器信息的作用,确保在集群中的各个节点间能够正确协调和执行...

    spring集成quartz集群配置

    在IT行业中,Spring框架是Java应用开发中的基石,而Quartz则是广泛...通过上述步骤,你已经掌握了Spring集成Quartz集群配置的基本概念。在实践中,根据具体需求调整配置,可以实现高效、稳定且可扩展的任务调度系统。

    Spring+Quartz 集群

    5. **集群配置**:为了实现高可用的Quartz集群,你需要配置多个节点共享同一个数据库存储的作业和触发器信息。Quartz支持多种持久化策略,如JDBC、RAMJobStore等,选择数据库存储能保证在集群中的任务状态一致性。 ...

    Springboot集成quartz集群

    本文章是关于springboot集成quartz集群的步骤,LZ亲测。

    quartz 集群配置

    当需要在分布式环境中运行多个Quartz实例以实现高可用性和负载均衡时,就需要进行Quartz集群配置。 在Spring集成Quartz的过程中,主要涉及以下几个核心概念和步骤: 1. **Job与Trigger**:Job是Quartz中的任务接口...

    quartz集群各种数据库建表脚本

    "quartz集群各种数据库建表脚本" 提供了在不同类型的数据库中创建Quartz集群所需的表结构。基于quartz2.2.1版本,这个脚本应该包含了创建必要的调度表,如QRTZ_JOB_DETAILS、QRTZ_TRIGGERS、QRTZ_SIMPLE_TRIGGERS等...

    Quartz集群配置和示例源码

    下面将详细阐述Quartz集群的配置以及示例源码的相关知识点。 **1. Quartz集群的核心概念** - **Job Store**: Quartz集群的关键在于共享任务存储,Job Store负责存储Job(任务)和Trigger(触发器)的信息。常见的...

    spring + quartz 集群配置

    java + quartz实现定时任务,实现集群配置,在集群环境下多节点运行定时Quartz定任务,就会存在重复处理任务的现象,为解决这一问题,下面我将介绍使用 Quartz 的 TASK ( 12 张表)实例化到数据库,基于数据库自动...

    Quartz集群简单资料(未整理)

    Quartz集群则是在单个Quartz实例的基础上,通过多台服务器的协作来提高系统的可用性和容错性,确保即使在单个节点故障时,作业仍然能够被正确地调度和执行。 在Quartz集群中,每个节点都是一个独立的Quartz ...

Global site tag (gtag.js) - Google Analytics