Xxl-job:调度中心分析

Xxl-job:调度中心分析:

一:根据设置的时间自动触发:
通过配置类XxlJobAdminConfig加载完属性文件后后初始化了一堆线程池(任务触发,任务注册,失败监控,回调处理,报表处理,按照时间任务处理),并启用

	public class XxlJobScheduler  {
private static final Logger logger = LoggerFactory.getLogger(XxlJobScheduler.class);


public void init() throws Exception {
    // init i18n
    initI18n();

    // admin trigger pool start
    JobTriggerPoolHelper.toStart();

    // admin registry monitor run
    JobRegistryHelper.getInstance().start();

    // admin fail-monitor run
    JobFailMonitorHelper.getInstance().start();

    // admin lose-monitor run ( depend on JobTriggerPoolHelper )
    JobCompleteHelper.getInstance().start();

    // admin log report start
    JobLogReportHelper.getInstance().start();

    // start-schedule  ( depend on JobTriggerPoolHelper )
    JobScheduleHelper.getInstance().start();

    logger.info(">>>>>>>>> init xxl-job admin success.");
}

}

重点关注:根据时间自动触发。

从原码来看,主要执行了两个线程。

  • scheduleThread:时间任务处理线程。
    1://悲观锁,并发处理
    preparedStatement = conn.prepareStatement( “select * from xxl_job_lock where lock_name = ‘schedule_lock’ for update” );

    2://拿到了距now 5秒内的任务列表数据:scheduleList,分三种情况处理:for循环遍scheduleList集合
                            List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
    
    3:根据触发算法去进行相应的处理
     * 对到达now时间后的任务:(超出now 5秒外):直接跳过不执行; 重置trigger_next_time;
     * 对到达now时间后的任务:(超出now 5秒内):线程执行触发逻辑; 若任务下一次触发时间是在5秒内, 则放到时间轮内(Map<Integer, List<Integer>> 秒数(1-60) => 任务id列表);再 重置trigger_next_time。
     * 未到达now时间的任务:直接放到时间轮内;重置trigger_next_time 。
    
  • ringThread:时间轮线程处理。
    入轮:扫描任务触发时 (1)本次任务处理完成,但下一次触发时间是在5秒内(2)本次任务未达到触发时间
    出轮:获取当前时间秒数,从时间轮内移出当前秒数前2个秒数的任务id列表, 依次进行触发任务;(避免处理耗时太长,跨过刻度,多向前校验一秒
    增加时间轮的目的是:任务过多可能会延迟,为了保障触发时间尽可能和 任务设置的触发时间尽量一致,把即将要触发的任务提前放到时间轮里,每秒来触发时间轮相应节点的任务

参考地址:https://www.cnblogs.com/wanghongsen/p/12510533.html

二:手动执行触发:JobInfoController里的triggerJob执行。fastpool线程池异步执行,选择路由测略,通过rpc调用执行器接口。

/**
 * run executor
 * @param triggerParam
 * @param address
 * @return
 */
public static ReturnT<String> runExecutor(TriggerParam triggerParam, String address){
    ReturnT<String> runResult = null;
    try {
        ExecutorBiz executorBiz = XxlJobScheduler.getExecutorBiz(address);
        runResult = executorBiz.run(triggerParam);//rpc调用
    } catch (Exception e) {
        logger.error(">>>>>>>>>>> xxl-job trigger error, please check if the executor[{}] is running.", address, e);
        runResult = new ReturnT<String>(ReturnT.FAIL_CODE, ThrowableUtil.toString(e));
    }

    StringBuffer runResultSB = new StringBuffer(I18nUtil.getString("jobconf_trigger_run") + ":");
    runResultSB.append("<br>address:").append(address);
    runResultSB.append("<br>code:").append(runResult.getCode());
    runResultSB.append("<br>msg:").append(runResult.getMsg());

    runResult.setMsg(runResultSB.toString());
    return runResult;
}



三:接受执行器注册请求:JobApiController,线程池异步执行通过数据库update索引加锁,保证并发。注册执行器插入xxl_job_registry表中。



public ReturnT<String> registry(RegistryParam registryParam) {

   // valid
   if (!StringUtils.hasText(registryParam.getRegistryGroup())
         || !StringUtils.hasText(registryParam.getRegistryKey())
         || !StringUtils.hasText(registryParam.getRegistryValue())) {
      return new ReturnT<String>(ReturnT.FAIL_CODE, "Illegal Argument.");
   }

   // async execute
   registryOrRemoveThreadPool.execute(new Runnable() {
      @Override
      public void run() {
         int ret = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registryUpdate(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());
         if (ret < 1) {
            XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().registrySave(registryParam.getRegistryGroup(), registryParam.getRegistryKey(), registryParam.getRegistryValue(), new Date());

            // fresh
            freshGroupRegistryInfo(registryParam);
         }
      }
   });

   return ReturnT.SUCCESS;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值