分布式调度平台XXL-JOB源码分析-调度中心2.1.0

官方文档执行器调度中心时序图

1.目标

在假勤项目中多次用到调度任务,此调度平台XXL-JOB是开源框架,很多公司在使用,通过理解XXL-JOB中的实现,更好的使用此工具,同时理解此工具运用在不同的调度场景使用。

上图是我们要进行源码分析的2.1版本的整体架构图。其分为两大块,调度中心(xxl-job-admin)和执行器(xxl-job-core业务代码使用),这次主要分析调度中心,也就是xxl-job-admin这个包的代码。

xxl-job官网链接:https://www.xuxueli.com/xxl-job

2.XXL-JOB如何实现任务调度的

在application.properties配置正确的数据库连接信息后,直接启动XxlJobAdminApplication即可。

配置类XxlJobAdminConfig,里面维护了一些调度中心端的配置数据。

XxlJobScheduler这个组件实现了InitializingBean接口,所以spring容器在初始化的时候会调用afterPropertiesSet方法,此方法如下:

核心调度逻辑在第五步JobScheduleHelper调度器,死循环,在xxl_job_info表里取将要执行的任务,更新下次执行时间的,调用JobTriggerPoolHelper类,来给执行器发送调度任务的。

JobScheduleHelper.java

这个类就是死循环从xxl_job_info表中取出未来5秒内要执行的任务,进行调度分发。
类的启动方法,建立了两个守护线程,1.scheduleThread 2.ringThread

先来看scheduleThread线程:
死循环内,首先利用for update语句进行获取任务的资格锁定,再去获取未来5秒内即将要执行的任务。
借鉴点1(包括优缺点):使用mysql行锁简单高效,比redis锁等稳定,在竞争不大的情况(对DB冲击小),不错的选择。
借鉴点2(包括优缺点):老版本调度中心使用quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而新版本xxljob调度中心抢占锁后,向执行器分发“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。
展开遍历任务的逻辑代码,有三个分支,
第一个分支当前任务的触发时间已经超时5秒以上了,不在执行,直接计算下一次触发时间:
第二个分支为触发时间已满足,利用JobTriggerPoolHelper这个类进行任务调度,之后判断下一次执行时间如果在5秒内,进行此任务数据的缓存,处理逻辑与第三个分支一样:
最后分支,未来5秒内执行任务,对触发时间秒数进行60取模,跟进pushTimeRing方法:
ringData是以0到59的整数为key,以jobId集合为value的Map集合。这个集合数据的处理逻辑,就在我们第二个守护线程ringThread中。
ringThread线程,根据当前秒数刻度和前一个刻度进行时间轮的任务获取,之后和上文一样,利用JobTriggerPoolHelper进行任务调度。

JobTriggerPoolHelper

如前文所述,不管是scheduleThread还是ringThread,最后完成任务调度的都是JobTriggerPoolHelper.trigger方法,这个类有两个线程池fastTriggerPool和slowTriggerPool,顾名思义,分别是执行较快任务和较慢任务的,后查官方文档,如下:
jobTimeoutCountMap属性,计数,key为jobId,value使用AtomicInteger计数。

helper静态变量指向自己本身,提供外部静态方法调用。
借鉴点3(包括优缺点):调度线程池隔离,拆分为”Fast”和”Slow”两个线程池,避免耗尽调度线程,提高系统稳
个人不太理解避免耗尽调度线程为什么非得是用2个线程池,1个改变最大线程数也够用,可能是方便管理+监控目前线程处理情况+方便定位问题,缺点是使用默认的拒绝策略,这里二次开发可以捕获异常等处理。

重要方法,向两种线程池其中之一提交调度任务,进行调度,引出XxlJobTrigger这个类,一路跟进去
至此,代码会处理路由策略和阻塞处理策略,最终完成执行器的任务调度。

3.路由策略与阻塞处理策略

  1. 路由策略:当执行器集群部署时,提供丰富的路由策略,包括;
  2. FIRST(第一个):固定选择第一个机器;
  3. LAST(最后一个):固定选择最后一个机器;
  4. ROUND(轮询):;
  5. RANDOM(随机):随机选择在线的机器;
  6. CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
  7. LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
  8. LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
  9. FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
  10. BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
  11. SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片参数开发分片任务;

  1. 单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
  2. 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
  3. 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;

4.业界开源JOB方案比对

总体来说,开源的方案各有优缺点,但没有一种方案能满足所有的需求。
相比较而言,xxl-job在配置方式、任务分组、使用界面、二次开发方面有优势,需要补全的功能较少。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值