浅析xxl-job
简介:
作为一个优秀的调度框架,今天整理一波xxl-job的复习资料
整体架构
- 整体架构分为调度器、执行器两个模块,互相解耦合
- 任务抽象称JobHandler,由执行器内的netty服务扫描管理中
-
执行流程
服务端启动流程
客户端启动
执行内嵌netty服务
- 使用netty开放端口,等待服务端调用
- 注册到服务端(心跳30S)
- 向服务端申请剔除服务
- 使用异步执行(每步都是启动线程完成任务)
服务注册
主动触发
自动触发
执行器挂掉如何保证数据准确
- job只是调度,调度时期挂掉,有任务失败线程校验是否重跑job调度
- job中的数据是否重复消费,在job调度的时候去具体的任务执行校验幂等
分片路由
-
- 分片的好处
- 并行处理
- 灵活控制并行数量
- 压力均匀分散到不同服务器节点
- 分片总数:任务器群中任务服务的数量
- 当前分片数:当前的下标,同一片任务机器中下标都不一样
- 即xxl-job调度中心发出一次调度,所有相关节点全部执行一次
- 通过任务参数传入执行任务节点数量
- 定时任务逻辑里,根据获取到的分片参数、执行任务节点数量,决策当前节点是否需要执行,分片查询数据并处理
- 如果分片序号 > (执行任务节点数量 - 1),则当前节点不执行任务,直接返回;
- 否则,取 分片序号 和 执行任务节点数量 作为分片参数,查询数据并处理。
增大并发度
- 如果需要更大的并发量,需要有大于应用节点数量的任务并行,如何处理?两种思路:
- 通过任务参数传入一个并发数,单个节点在处理任务时,将查询到的数据按这个数字进行再分片,交由线程池并行处理;
- 配置 M 个定时任务,指定相同的 JobHandler,给它们编号 0、1、2…M,并将定时任务编号和 M 这两个数,由任务参数传入,定时任务逻辑里,先根据分片参数、定时任务编号、M,重新计算出新的分片参数,如分片序号 = (分片序号 * M) + 定时任务编号,分片总数 = 分片总数 * M,再查询数据并处理。
- 如果有可能频繁调整任务执行逻辑,包括可能要新增任务参数等,而不想重启服务器,如何解决?
- 可以考虑使用 XXL-JOB 的「GLUE模式」任务,能够在线编辑和更新定时任务执行逻辑。
加锁
- JDBC自己管理数据库链接
- 取消事务自动提交,使用for update写锁
- 一般情况下查询的时候,默认数据库加读锁,这种级别是很低的,当xxjob存在集群部署的时候,存在多个线程争抢查询数据库,会造成触发器重复执行。为了防止这种情况,设置手动提交(这里spring会默认自动提交),查询添加写锁(for update)。在此期间其他线程访问的时候都会阻塞等待。