XXL-JOB
2024-7-1
| 2025-3-11
字数 1667阅读时长 5 分钟
type
status
date
slug
summary
tags
category
icon
password
AI summary
Last edited time
Mar 11, 2025 03:50 PM
 

核心执行逻辑(版本2.2.0)

 
com.xxl.job.admin.core.thread.JobScheduleHelper#start
 

scheduleThread

该线程负责从数据库中预读将要执行的任务,并将其放入到 ringData 中用于后续真正的调度线程进行调度
1. 线程初始化
  • 创建了一个新的线程 scheduleThread,并实现了 Runnable 接口的 run 方法。
 
2. 线程启动前的延迟
  • 线程启动后,首先会休眠一段时间,确保线程在整秒时刻启动(即 System.currentTimeMillis() % 1000 为 0 的时刻)。这样可以使得后续的调度任务能够对齐到整秒。
 
3. 预读任务数量计算
  • 计算预读任务的数量。preReadCount 是根据线程池的大小和触发器的 QPS(每秒查询率)来计算的。假设每个触发器耗时 50ms,那么 QPS 为 20(1000ms / 50ms)
 
4. 主循环
  • 主循环会一直运行,直到 scheduleThreadToStop 被设置为 true
 
5. 数据库连接与事务管理
  • 获取数据库连接,并开启事务。通过 for update 语句锁定 xxl_job_lock 表中的 schedule_lock 记录,确保在同一时间只有一个调度线程在执行
  • 这里要思考如果获取到数据库悲观锁之后,JVM挂掉,会不会一直无法释放锁导致其他节点无法获取数据库悲观锁
 
6. 预读任务
  • 从数据库中预读即将触发的任务列表。nowTime + PRE_READ_MS 表示预读的时间范围,preReadCount 是预读的任务数量。
7. 任务处理
  • 遍历预读的任务列表,根据任务的触发时间进行不同的处理:
    • 任务过期:如果任务的触发时间已经超过预读时间范围,则标记任务为过期,并更新下一次触发时间。
    • 任务触发:如果任务的触发时间在当前时间和预读时间之间,则立即触发任务,并更新下一次触发时间。
    • 任务预读:如果任务的触发时间在未来,则将任务放入时间环中,等待后续触发。
 
8. 更新任务信息
  • 更新数据库中任务的信息,确保任务的触发时间和状态是最新的。
 
9. 事务提交与资源释放
  • 提交事务,并释放数据库连接和 PreparedStatement 资源。
 
10. 等待下一次调度
  • 如果本次调度耗时小于 1 秒,则线程会休眠一段时间,确保下一次调度在整秒时刻执行。
 

ringThread

该线程负责时间轮的推进(单位为秒),并执行对应的任务
 
1. 线程初始化
 
2. 线程启动前的延迟
  • 熟悉的操作,线程启动后,首先会休眠一段时间,确保线程在整秒时刻启动(即 System.currentTimeMillis() % 1000 为 0 的时刻)。这样可以使得后续的时间环任务能够对齐到整秒。
 
3. 主循环
 
4. 获取当前秒数
  • 获取当前的秒数(0-59),用于确定当前时间环的位置。
 
5. 从时间环中获取任务
  • 从时间环数据结构 ringData 中获取当前秒和前一秒的任务列表。
    • ringData 是一个以秒为索引的哈希表,存储了每个秒数对应的任务列表。
    • (nowSecond + 60 - i) % 60 用于计算当前秒和前一秒的索引,避免跨过刻度。
    • 如果某个秒数对应的任务列表存在,则将其合并到 ringItemData 中。
 
6. 触发任务
  • 如果 ringItemData 中有任务,则遍历任务列表并触发每个任务。
    • JobTriggerPoolHelper.trigger 是触发任务的核心方法,会根据任务 ID 执行相应的任务。
  • 触发完成后,清空 ringItemData,以便下一次使用。
 
7. 异常处理
  • 捕获并记录线程运行过程中发生的异常。如果线程未被要求停止(ringThreadToStop 为 false),则记录错误日志
 
8. 等待下一次触发
  • 线程休眠一段时间,确保下一次触发在整秒时刻执行。休眠时间通过 1000 - System.currentTimeMillis() % 1000 计算,保证对齐到整秒。
 
com.xxl.job.admin.core.thread.JobScheduleHelper#toStop
停止时,会先停止预读任务线程,如果有待执行的任务,还会 sleep 8秒等待相应的任务被调度完成
 
  • XXL-JOB
  • Docker 常用操作UFW 防火墙配置
    Loading...