分布式任务调度框架

分布式任务调度框架


学习为主

文章目录



分布式调度平台大多殊途同归。

关于xxl-JOB

一、概念

XXL-JOB是一个轻量级分布式任务调度平台,主打特点是平台化,易部署,开发迅速、学习简单、轻量级、易扩展,代码仍在持续更新中。本身是任务调度控制台,不承担业务逻辑,我们常常拿这个当作定时任务,一些特性什么这里就不过多介绍了。重点是大体的流程和原理。

二、架构图

xxl-job其实也是在quartz的基础上实现的,但是修改了任务调度的模式,并且任务调度采用注册和RPC调用方式来实现。

2.1.0版本前核心调度模块都是基于quartz框架,2.1.0版本开始自研调度组件,移除quartz依赖 ,使用时间轮调度。

(RPC的底层变化, 2.0.1 使用的是Jetty服务的RPC, 2.0.2 使用的Nettty服务的RPC)

三、任务调度的流程

1:XXL-Jobadmin平台创建执行器(Job实际执行地址)

2:XXL-Jobadmin平台新建任务,填写对应的执行器

3:Job服务器代码中,使用JobHandler表示该类为Job执行方法

4:当任务执行的时候,会现在XXL-Jobadmin调度平台先执行一次,获取任务中的执行器,然后去对应的执行器地址服务器,执行对应的任务

定时触发任务是如何实现的?:使用时间轮实现

xxl_job_info表是记录定时任务的db表,里面有个trigger_next_time(Long)字段,表示下一次触发的时间点任务时间被修改 / 每一次任务触发后,可以根据cronb表达式计算下一次触发时间戳:

java 复制代码
Date nextValidTime = new CronExpression(jobInfo.getJobCron()).getNextValidTimeAfter(new Date()))

更新trigger_next_time字段

定时执行任务逻辑:

  • 定时任务scheduleThread:不断从db把5秒内要执行的任务读出,立即触发 / 放到时间轮等待触发,并更新trigger_next_time
  • 获取当前时间now
  • 轮询db,找出trigger_next_time在距now 5秒内的任务

3.1 对到达now时间后的任务(超出now 5秒外)

​ (1) 直接跳过不执行;

​ (2) 重置trigger_next_time

3.2 对到达now时间后的任务(超出now 5秒内)

​ (1) 开线程执行触发逻辑;

​ (2) 若任务下一次触发时间是在5秒内,则放到时间轮内(Map<Integer, List>秒数(1-60) => 任务id列表);

​ (3) 重置trigger_next_time

3.3 对未到达now时间的任务

​ (1)直接放到时间轮内;

​ (2)重置trigger_next_time

  • 定时任务ringThread:时间轮实现到点触发任务

4.1 时间轮数据结构:Map<Integer, List> key是秒数(1-60) ,value是任务id列表

  • 获取当前时间秒数
  • 从时间轮内移出当前秒数前2个秒数(避免处理耗时太长,跨过刻度,向前校验一个刻度)的任务列表id,一一触发任务;

如何避免集群中的多个服务器同时调度任务?

当xxl-job应用本身集群部署(实现高可用HA)时,如何避免集群中的多个服务器同时调度任务?

通过mysql悲观锁实现分布式锁(for update语句)

  • setAutoCommit(false)关闭隐式自动提交事务,启动事务
  • select lock for update(显式排他锁,其他事务无法进入&无法实现for update)
  • 读db任务信息 -> 拉任务到内存时间轮 -> 更新db任务信息
  • commit提交事务,同时会释放for update的排他锁(悲观锁)

任务执行器注册中心是如何实现的?

使用db表xxl_job_group记录下执行器的信息:

执行器AppName、执行器名称title、执行器地址列表address_list(多地址逗号分隔)

如何实现任务执行器的路由?

执行器集群部署时提供丰富的路由策略,包括:

第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;

  • 第一个、最后一个、轮询、随机:都是简单读address_list即可
  • 一致性HASH:TreeSet实现一致性hash算法
  • 最不经常使用、最近最久未使用:HashMap、LinkedHashMap
  • 故障转移:遍历address_list获取address时,逐个检查该address的心跳(请求返回状态);只有心跳正常的address才返回使用
  • 忙碌转移:遍历address_list获取address时,逐个检查该address是否忙碌(请求返回状态);只有状态为idle的address才返回使用

如何实现任务分片、并行执行?

  • 拉出任务的执行机器列表,逐个设置index / total,把index / total分发到任务执行器
  • 任务执行器可根据index / total参数开发分片任务


学习1:https://www.kuaiyong.icu/xxl_job定时任务管理平台/

学习2:https://blog.csdn.net/weixin_40816738/article/details/123720235

相关推荐
企微自动化17 小时前
企业微信二次开发:深度解析外部群主动推送的实现路径
java·开发语言·企业微信
_修铁路的17 小时前
【Poi-tl】 Word模板填充导出
java·word·poi-tl
武子康17 小时前
Java-216 RocketMQ 4.5.1 在 JDK9+ 从0到1全流程启动踩坑全解:脚本兼容修复(GC 参数/CLASSPATH/ext.dirs)
java·大数据·分布式·消息队列·系统架构·rocketmq·java-rocketmq
austin流川枫18 小时前
🔥MySQL的大表优化方案 (实战分享)
java·mysql·性能优化
码界奇点18 小时前
基于Spring Boot和Vue.js的视频点播管理系统设计与实现
java·vue.js·spring boot·后端·spring·毕业设计·源代码管理
爱吃山竹的大肚肚18 小时前
MySQL 支持的各类索引
java·数据库·sql·mysql·spring·spring cloud
程序员水自流18 小时前
MySQL常用内置函数详细介绍
java·数据库·mysql
廋到被风吹走18 小时前
【Spring】Spring Boot详细介绍
java·spring boot·spring
期待のcode18 小时前
Java中的继承
java·开发语言
计算机毕设指导618 小时前
基于微信小程序的智慧社区娱乐服务管理系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·娱乐