数据平台-调度系统(1)-quartz

在数据平台中,每天都会有上万个任务进行流转,如何准确,实时的完成任务,是非常关键的一步。公司在发展的过程经历了azikaban->airflow->dataflow(自研airflow支持k8s)->kepler的一个过程。目前使用的调度系统任务3w+,日执行10w+。上线0事故,非常稳定的运行。

底层调度器用的是quartz,写调度系统之前肯定要了解调度器的源码。于是记录下。

Quartz是Java领域著名的开源任务调度工具。Quartz提供了极为广泛的特性如持久化任务,集群和分布式任务等,其特点如下:

  • 完全由Java写成,方便集成(Spring)
  • 伸缩性
  • 负载均衡
  • 高可用性
使用方式

我们的使用姿势是 springboot+quartz

配置文件

quartz.org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
quartz.org.quartz.threadPool.threadCount=10
quartz.org.quartz.threadPool.threadPriority=5

quartz.org.quartz.scheduler.instanceName=kepler
quartz.org.quartz.scheduler.instanceId=AUTO
quartz.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
quartz.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
quartz.org.quartz.jobStore.useProperties=false
quartz.org.quartz.jobStore.tablePrefix=QRTZ_
quartz.org.quartz.jobStore.isClustered=true
quartz.org.quartz.jobStore.misfireThreshold=1800000
quartz.org.quartz.jobStore.clusterCheckinInterval=5000
quartz.org.quartz.jobStore.dataSource=quartzDataSource

quartz.org.quartz.dataSource.quartzDataSource.provider=hikaricp
quartz.org.quartz.dataSource.quartzDataSource.poolName=hikari-quartz
quartz.org.quartz.dataSource.quartzDataSource.driver=${
   mysql.driver-class-name}
quartz.org.quartz.dataSource.quartzDataSource.URL=${
   mysql.jdbc-url}
quartz.org.quartz.dataSource.quartzDataSource.user=${
   mysql.username}
quartz.org.quartz.dataSource.quartzDataSource.password=${
   mysql.password}
quartz.org.quartz.dataSource.quartzDataSource.maximumPoolSize=${
   mysql.maximum-pool-size}
quartz.org.quartz.dataSource.quartzDataSource.connectionTestQuery=${
   mysql.connection-test-query}
quartz.org.quartz.dataSource.quartzDataSource.connectionTimeout=${
   mysql.connection-timeout}
quartz.org.quartz.dataSource.quartzDataSource.idleTimeout=${
   mysql.idle-timeout}
quartz.org.quartz.dataSource.quartzDataSource.maxLifetime=${
   mysql.max-lifetime}
Scheduler sched = SchedulerFactory.getScheduler(config);
JobDetail jobDetail = JobBuilder.newJob(jobClass)
                             .withIdentity(jobName, HM_JOB)//任务名称和组构成任务key
                            .build();
jobDetail.getJobDataMap().putAll(data);
            // 触发器
SimpleTrigger trigger = TriggerBuilder.newTrigger()
                           .withIdentity(jobName, HM_TRIGGER)//触发器key
                           .startAt(DateBuilder.futureDate(1, IntervalUnit.SECOND))
                           .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                           .withIntervalInSeconds(interval)
                           .repeatForever())
                           .build();

sched.scheduleJob(jobDetail, trigger);
            // 启动
if (!sched.isShutdown()) {
   
    sched.start();
}
工作原理

Quartz是通过对用户暴露出Scheduler来进行任务的操作,它可以把任务JobDetail和触发器Trigger加入任务池中,可以把任务删除,也可以把任务停止,scheduler把这些任务和触发器放到一个JobStore中,这里jobStore有内存形式的也有持久化形式的,当然也可以自定义扩展成独立的服务。

  1. Job就是自定义业务的接口,里面就一个execute方法,线程运行Job时会把JobDataMap封装到JobExecutionContext里作为execute方法的参数,jobdetail是对job的封装,里面有Job的class,对应的数据, 名称,分组等
  2. Trigger是触发器,job下次什么时候执行存放在trigger中
  3. QuartzSchedulerResources相当于调度的资源存放器,包含了JobStore, ThreadPool等资源,调度都是通过 QuartzSchedulerResources获取相关属性的。
  4. jobStore是任务和触发器存储地方,它里面提供大量类似于增删改的操作任务方法。
  5. QuartzSchedulerThread是一个调度线程,ThreadPool是一个执行线程池。里面有workerThread来执行用户任务
源码分析

根据上面的使用流程,逐个来分析源码过程

首先获取Scheluer
Scheduler scheduler = StdSchedulerFactory.getScheduler(config);

StdSchedulerFactory根据配置文件来生成Scheduler。
1.

    public Scheduler getScheduler() throws SchedulerException {
   
    //参数没传的话,则读取默认的配置
        if (cfg == null) {
   
        //初始化配置文件
            initialize();
        }

        SchedulerRepository schedRep = SchedulerRepository.getInstance();

        Scheduler sched = schedRep.lookup(getSchedulerName());

        if (sched != null)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值