背景
- 之前写过一个分布式任务调度的demo: spring-distributed-quartz
- 公司也有自己的分布式任务调度、所以认真研究、好好学习。
Quartz优缺点
首先说Quartz+MySQL持久化优点
- 实现了分布式情况下的任务调度、并且与spring-boot(即使不引入starter也是可以的、starter里面只有一个META-INF文件)结合,易于开发。
- quartz开源早,博客使用示例多,出现问题易于解决。
Quartz缺点
- 需要把任务信息持久化到业务数据库、和业务有耦合、并且表比较多。
- 调度逻辑和执行逻辑存在同一个项目中、在机器性能固定的情况下、业务和调度之间不可避免会相互影响。
- quartz+mysql集群模式下、是通过mysql的独占锁来唯一获取任务、任务执行并没有实现完善的负载均衡。
Quartz相关问题
- 调度器(Scheduler)和执行器(Job)
- 具体执行流程是怎样的
- 调度器是如何推送的 任务分为一次性和cron定时性的(如果在调度过程中调度器挂了会怎么样)
- 调度器是如何保证只执行一次的
- Quartz的mysql有很多数据库表、都是什么含义。
从Quartz中我们能学到什么?
- 集群环境下一种防止并发的实现。
- 创建锁 TB_LOCKS表
- 创建记录表 记录所表示的PREV_FIRE_TIME时间
- 通过select for update 竞争锁、竞争到后查看执行时间是否满足。 类似java代码的 sychronized然后再check一下。
- Quartz Scheduler单例模式
- Quartz的job重复执行问题
triggers = qsRsrcs.getJobStore().acquireNextTriggers(now + idleWaitTime, Math.min(availThreadCount, qsRsrcs.getMaxBatchSize()),
qsRsrcs.getBatchTimeWindow());
- SchedulerFactoryBean => FactoryBean
如何提升类似像XXL-Job等性能
首先关于开源的分布式任务调度系统,其核心调度模块比如Quartz或者自身的自实现Quartz本质还是强依赖数据库性能,虽然可以通过集群部署应用达到高可用,但是存在着明显的性能瓶颈。
那么如何提升呢? 核心就是拆、从BG、集群、任务组等拆分,从执行的读库到读内存的DelayQueue、再到线程池,快慢线程池等。
- 如果是企业级的分布式调度平台,不要把鸡蛋放到一个篮子,或者在内部不要放在一个篮子,即通过一定方式进行分区,比如按照BG等拆分到不同集群(不同集群间是隔离的,比如数据库等)
- 在BG下再拆分到不同机器上,做主从高可用。任务本身不要强依赖数据库,只加载,异步存储保证性能。
- 任务拆分可以依赖分片思想拆分。
相关资料
Quartz使用和详细流程 https://www.cnblogs.com/wuzhenzhao/p/11751504.html