说完了xxl-job的执行器原理,再来聊聊调度中心是如何调度任务的

说完了xxl-job的执⾏器原理,再来聊聊调度中⼼是如何调度任务
金宏柱前⾔
在上⼀篇 ⼀⽂中,我们提到了 xxl-job 框架中包含了两个核⼼模块:调度中⼼ 和 执⾏器, 其中调度中⼼主要负责 任务的调度 , ⽽执⾏器负责 任务的执⾏, 两者各司其职。 紧接着我们通过画图的⽅式对 执⾏器 的内部构造进⾏了分析,并且还对 Job 的执⾏流程进⾏了梳理。
本⽂我们继续围绕任务的调度流程对 调度中⼼ 进⾏剖析, 内容依然参照 xx-job v2.x 版本的源码。
正⽂
再看⼀遍 xxl-job 架构图:
调度中⼼主要提供了两个功能: 系统管理 和 任务调度。其余的都是⼀些辅助功能。
系统管理正如图中所⽰的那样, 包括任务管理、执⾏器管理、⽇志管理。还提供了管理界⾯。
任务调度就是负责从数据中⼼拉取任务,并按照执⾏时间将任务投递给执⾏器。
调度器的组成结构
两个核⼼线程
当调度中⼼启动后,会启动以下两个线程:
1. schedulerThread
scheudlerThread主要做如下两件事情:
从数据中⼼(db),也就是 xxl_job_info表中扫描出符合 条件 1 的任务, 条件1 限制如下:
任务执⾏时间 ⼩于(当前时间 + 5 s)
限制扫描个数, 这个值是动态的,会根据后⾯的提到的 快慢线程池 中线程数量有关系。
count = treadpool-size * trigger-qps  (each trigger cost 50ms, qps =1000/50=20)阎健宏>綦江洪水
treadpool-size =(getTriggerPoolFastMax()+getTriggerPoolSlowMax())*20
// 看完快慢线程池的介绍,再回过头来看这⾥,会更容易理解
扫描出来的任务被划分为以下 3 类:
2. ringThreadaxara
ringThread的作⽤就是不断从 容器 中读取 当前时间点需要执⾏ 的任务, 读取出来的任务会交给⼀个叫 快慢线程池 的东西去将任务传递给调度器去执⾏。
控制系统时间轮
上述的 ringThread和 容器 共同组成了⼀个时间轮。
关于时间轮,如果展开来讲内容会很多,需要详细了解的可以参考 ,或者⾃⾏搜索, 本⽂只做简单了解。
简单来讲,时间轮实现了 延迟执⾏ 的功能,它在 xxl-job 中的作⽤就是让 还未到达执⾏时间 的任务,按照预计的时间通过 快慢线程池 ⼀个⼀个送到 执⾏器 中去执⾏。
时间轮的数据结构⼀般是 数组 + 链表, 和 jdk1.7 中的 HashMap 是⼀个道理,链表中的每个节点就是⼀个待执⾏的任务。
xxl-job 中的时间轮可以形象描述为以下这张图,像⼀个只有秒针的钟表⼀样。
ringThread 线程运⾏过程中,每秒会扫过⼀个刻度,假设当前刻度位置存在 job 链表,就把链表中的所有 job 取出来,最后丢给 快慢线程池。
当然 xxl-job 为了避免处理耗时太长,会跨过刻度,多向前校验⼀个刻度;也就是当指针指到 2s 时,会把 1s 和 2s 位置的任务同时读取出来。
快慢线程池
上⾯提到任务从数据中⼼扫描出来后,随之就会被丢到快慢线程池中,快慢线程池的定义如下:
fastTriggerPool =new ThreadPoolExecutor(
10,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000),
new ThreadFactory(){
@Override
public Thread newThread(Runnable r){
return new Thread(r,"xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-"+ r.hashCode());
}
});
slowTriggerPool =new ThreadPoolExecutor(
10,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(2000),
new ThreadFactory(){
@Override
public Thread newThread(Runnable r){
return new Thread(r,"xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-"+ r.hashCode());
}
禁播水浒});
由上可知, 快慢线程池包含了两个线程池 fast 和 slow,当⼀个 job 提交到快慢线程池后,快慢线程池会根据⼀些条件, 选择其中⼀个线程池去执⾏后续的操作。
快慢线程池的作⽤如下:
实现线程池隔离:调度线程池进⾏隔离拆分,慢任务⾃动降级进⼊”Slow”线程池,避免耗尽调度线程,提⾼系统稳定性;
什么是慢任务?
如果⼀个任务在 1 分钟内,它的执⾏超时次数超过 10 次,就被归为慢任务
当具体的快或者慢线程池接收到调度任务时,会通过 RPC 远程调⽤去触发 执⾏器 完成任务的执⾏逻辑。
当执⾏器接收到调度任务时,具体是如何执⾏任务的,可以参考 ⼀⽂。
源码⼊⼝
总结
本⽂基于 xxl-job v2.x 的源码分析了 xxl-job 调度器的组成结构 以及 调度中⼼是如何触发任务的。
调度器主要包含了以下模块:
schedulerThread: 负责从数据中⼼扫描需要执⾏的任务
ringThread: 负责精准地控制预计需要执⾏的任务
快慢线程池:通过包装两个线程池,去分别执⾏ 快任务 和 慢任务 的调度过程。
这⾥⾯的主要难点是引出了⼀个时间轮的概念,⽂中并未做详细的描述,另外时间轮的⽤法在很多地⽅都有应⽤, ⽐如 Netty、Dubbo、Kafka 等。
最后,本⽂中仍有很多细节没有展开来讲,需要读者⾃⾏去挖掘。

本文发布于:2024-09-21 23:30:38,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/284535.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:任务   线程   调度   时间
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议