背景

  1. 之前写过一个分布式任务调度的demo: spring-distributed-quartz
  2. 公司也有自己的分布式任务调度、所以认真研究、好好学习。

Quartz优缺点

首先说Quartz+MySQL持久化优点

  1. 实现了分布式情况下的任务调度、并且与spring-boot(即使不引入starter也是可以的、starter里面只有一个META-INF文件)结合,易于开发。
  2. quartz开源早,博客使用示例多,出现问题易于解决。

Quartz缺点

  1. 需要把任务信息持久化到业务数据库、和业务有耦合、并且表比较多。
  2. 调度逻辑和执行逻辑存在同一个项目中、在机器性能固定的情况下、业务和调度之间不可避免会相互影响。
  3. quartz+mysql集群模式下、是通过mysql的独占锁来唯一获取任务、任务执行并没有实现完善的负载均衡。

Quartz相关问题

  1. 调度器(Scheduler)和执行器(Job)
  2. 具体执行流程是怎样的
  3. 调度器是如何推送的 任务分为一次性和cron定时性的(如果在调度过程中调度器挂了会怎么样)
  4. 调度器是如何保证只执行一次的
  5. Quartz的mysql有很多数据库表、都是什么含义。

从Quartz中我们能学到什么?

  1. 集群环境下一种防止并发的实现。
    1. 创建锁 TB_LOCKS表
    2. 创建记录表 记录所表示的PREV_FIRE_TIME时间
    3. 通过select for update 竞争锁、竞争到后查看执行时间是否满足。 类似java代码的 sychronized然后再check一下。
  2. Quartz Scheduler单例模式
  3. Quartz的job重复执行问题
triggers = qsRsrcs.getJobStore().acquireNextTriggers(now + idleWaitTime,  Math.min(availThreadCount, qsRsrcs.getMaxBatchSize()),
qsRsrcs.getBatchTimeWindow());
  1. SchedulerFactoryBean => FactoryBean

如何提升类似像XXL-Job等性能

首先关于开源的分布式任务调度系统,其核心调度模块比如Quartz或者自身的自实现Quartz本质还是强依赖数据库性能,虽然可以通过集群部署应用达到高可用,但是存在着明显的性能瓶颈。

那么如何提升呢? 核心就是拆、从BG、集群、任务组等拆分,从执行的读库到读内存的DelayQueue、再到线程池,快慢线程池等。

  1. 如果是企业级的分布式调度平台,不要把鸡蛋放到一个篮子,或者在内部不要放在一个篮子,即通过一定方式进行分区,比如按照BG等拆分到不同集群(不同集群间是隔离的,比如数据库等)
  2. 在BG下再拆分到不同机器上,做主从高可用。任务本身不要强依赖数据库,只加载,异步存储保证性能。
  3. 任务拆分可以依赖分片思想拆分。

相关资料

Quartz使用和详细流程 https://www.cnblogs.com/wuzhenzhao/p/11751504.html