xxljob执行源码分析

简介: 本文深入解析XXL-JOB分布式任务调度框架源码,涵盖架构设计、核心执行流程与关键线程池机制。内容包括任务触发、注册、失败重试、日志报告及时间轮调度原理,结合带中文注释的源码包与分析导图,全面剖析其高性能设计实现。

已包含中文注释的源码压缩包:📎xxl-job-master.zip

分析流程:📎xxljob直播.xmind

1.架构分析

2.执行源码

核心代码位置如下:

1-initI18n()

  • 初始化国际化资源,对应配置文件:resources:i18n

2-JobTriggerPoolHelper.toStart()

触发器线程池:创建快慢线程池,提升任务执行效率

  • 如果一个任务在1min内超过10次提交,就默认是慢任务,为了防止慢任务影响系统吞吐量,将其放在慢线程池中运行
  • 快线程池定义:最大线程数=200,等待队列=1000
  • 慢线程池定义:最大线程数=100,等待队列=2000

addTrigger方法

  • 默认选择快线程池,如果任务在1min内超过10次提交,就是慢线程池
  • 真正的触发器操作代码

3-JobRegistryHelper.getInstance().start()

任务注册器线程池:将上线机器刷新(最近90s有心跳),将下线机器移除(90s内没心跳),更新执行组

  • 初始化服务上线/下线线程池:将新增的IP添加到组中,将断线的IP及时清理(因为执行器会上下线,xxl-job会保证及时更新当前在线的执行器)
  • 初始化心跳检测的线程池:xxl-job会把心跳信息保存在xxl_job_registry,借助心跳检测机制,保证机器下线能够及时清楚,机器上线及时发现

4-JobFailMonitorHelper.getInstance().start()

重试报警机制:因为任务是异步调用,需要有一个进程持续监听执行结果,主要做的是:读取本地数据,更新数据状态,未达到失败次数就重试,达到失败次数就告警

  • 借助mybatis查询本地数据库执行失败、且告警状态=0[未告警]的数据日志ID,读取表:xxl_job_log
  • 更新告警状态=-1[锁定,避免多线程并发干扰],0-默认、-1=锁定状态、1-无需告警、2-告警成功、3-告警失败
  • 基于日志ID取出完整的日志信息,读取表:xxl_job_log
  • 基于ID获取失败日志对应的任务信息,读取表:xxl_job_info
  • 如果失败任务可充实次数大于0,表示还能重试,就继续重试
  • 如果配置了告警信息,就实现报警
  • 报警后更新本地告警状态,2或3

5-JobCompleteHelper.getInstance().start()

调度系统调度执行器后,执行器突然宕机,调度系统就可以根据这个线程感知任务到底执行成功还是失败

  • 任务结果丢失处理:调度记录停留在 "运行中" 状态超过10min,且对应执行器心跳注册失败不在线,则将本地调度主动标记失败;

6-JobLogReportHelper.getInstance().start()

  • 清理过期日志,没什么需要详细讲解的

7-JobScheduleHelper.getInstance().start()

从xxl_job_info表中找出当前时间+5s的所有执行器数据,然后根据其调度时间判断立即调度还是加入时间戳

  • 取出当前时间 + 5s内所有待执行的执行器数据(避免循环本身导致错过执行时间)
  • 建立数据库链接
  • 关闭事务的自动提交
  • 悲观锁,锁定数据
  • 过期处理策略

可能过期的原因:服务重启;调度线程被阻塞,线程被耗尽;上次调度持续阻塞,下次调度被错过

  • 从数据库取出当前时间+5s的所有任务
  • 当前时间:超过调度时间+5s
  • 判断任务执行状态是否是:FIRE_ONCE_NOW,如果是就立马调度一次
  • 刷新调度时间,避免下一次再错过
  • 当前时间:超过调度时间,但还没超过5s
  • 调度一次
  • 更新调度时间,避免下一次再错过
  • 当前时间:没超过调度时间,把调度时间加入到时间轮中
  • 获取调度时间的秒
  • 将调度时间作为key,任务id作为value,放进调度任务时间轮的map中(其执行代码在:238行)
  • 刷新下一次调度时间(这里就不是new Date()了,而是真实的执行时间)
  • 更新每一个任务的最近一次执行时间、下一次执行时间、执行状态

时间轮执行原理

时间轮执行原理:com.xxl.job.admin.core.thread.JobScheduleHelper#ringThread

  • 先延迟0-1秒,以保证加载所有数据
  • 获取当前时间对应的秒数
  • 避免处理耗时太长,跨过刻度,向前校验一个刻度
  • 这里的ringData就是上面场景3中添加进去的数据,当前文件代码:149行
  • 当前秒+1是为了防止时间轮中的任务由于意外没有执行,从而有一个补偿机制
  • 调度任务
  • 清空已处理数据

相关文章
|
12天前
|
数据采集 人工智能 安全
|
7天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
344 164
|
6天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
345 155
|
7天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
581 4
|
15天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
1019 7

热门文章

最新文章