开整,开整!!xxl-job调度器源码启动流程搞起!

小强前几天又催我了!拖不住了,源码开整!!
为了让大家由浅入深的理解源码,总体路线按照 调度器源码启动流程 -> 执行器源码启动流程 -> 任务调度核心源码,后面也会补充xxl-job的踩过的一些坑,以及定制化开发。
前置讲完了,撸起袖子开整!!走起,让我们先去看下任务调用端做了哪些事!!

image.png

1.任务调用端Admin启动入口

1715078976252.png

启动的入口类为XxlJobAdminConfig类

@Component
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
   

    private static XxlJobAdminConfig adminConfig = null;
    public static XxlJobAdminConfig getAdminConfig() {
   
        return adminConfig;
    }


    // ---------------------- XxlJobScheduler ----------------------

    private XxlJobScheduler xxlJobScheduler;

    @Override
    public void afterPropertiesSet() throws Exception {
   
        adminConfig = this;

        xxlJobScheduler = new XxlJobScheduler();
        xxlJobScheduler.init();
    }

    @Override
    public void destroy() throws Exception {
   
        xxlJobScheduler.destroy();
    }
}

先看下启动类XxlJobAdminConfig,这个启动类继承了InitializingBean,所以在项目启动的情况下会触发
afterPropertiesSet方法进行初始化,在初始化中构建XxlJobScheduler对象,并且调用init()初始化。

    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.");
    }

主要干的事:

  1. init i18n
  2. 初始化线程池,包含快慢两个线程池
  3. 负责执行器的注册和移除,维护注册表信息
  4. 任务执行监控
  5. 任务调度

2.启动流程

2.1 初始化触发线程池

    public void start(){
   
        //最大200个线程
        fastTriggerPool = new ThreadPoolExecutor(
                10,
                XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax(),
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(1000),
                new ThreadFactory() {
   
                    @Override
                    public Thread newThread(Runnable r) {
   
                        return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-fastTriggerPool-" + r.hashCode());
                    }
                });

        //当任务再一分钟内超过10次时,会放入到慢触发器执行
        slowTriggerPool = new ThreadPoolExecutor(
                10,
                XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax(),
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(2000),
                new ThreadFactory() {
   
                    @Override
                    public Thread newThread(Runnable r) {
   
                        return new Thread(r, "xxl-job, admin JobTriggerPoolHelper-slowTriggerPool-" + r.hashCode());
                    }
                });
    }	

关键:这里会初始化两个线程池,分别是快慢线程池。
快线程池用于处理时间短的任务,慢线程池用于处理时间长的任务。
当任务执行时,优先选择快触发器,当一分钟以内任务超过10次执行时间超过500ms时,则放到慢线程池触发器执行,这块可以把快慢任务进行隔离。

2.2 维护注册信息

主要有有两个线程池

	public void start(){
   
		// 负责注册或者移除执行器的线程池
		registryOrRemoveThreadPool = new ThreadPoolExecutor(
				2,
				10,
				30L,
				TimeUnit.SECONDS,
				new LinkedBlockingQueue<Runnable>(2000),
				new ThreadFactory() {
   
					@Override
					public Thread newThread(Runnable r) {
   
						return new Thread(r, "xxl-job, admin JobRegistryMonitorHelper-registryOrRemoveThreadPool-" + r.hashCode());
					}
				},
				new RejectedExecutionHandler() {
   
					@Override
					public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
   
						r.run();
						logger.warn(">>>>>>>>>>> xxl-job, registry or remove too fast, match threadpool rejected handler(run now).");
					}
				});

		// 剔除超时执行器线程池
		registryMonitorThread = new Thread(new Runnable() {
   
			@Override
			public void run() {
   
				while (!toStop) {
   
					try {
   
						// auto registry group
						List<XxlJobGroup> groupList = XxlJobAdminConfig.getAdminConfig().getXxlJobGroupDao().findByAddressType(0);
						if (groupList!=null && !groupList.isEmpty()) {
   

							// remove dead address (admin/executor)
                            // 获取90s内没有发送心跳的执行器
							List<Integer> ids = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findDead(RegistryConfig.DEAD_TIMEOUT, new Date());
							if (ids!=null && ids.size()>0) {
   
								XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().removeDead(ids);
							}

							// fresh online address (admin/executor)
							HashMap<String, List<String>> appAddressMap = new HashMap<String, List<String>>();
							List<XxlJobRegistry> list = XxlJobAdminConfig.getAdminConfig().getXxlJobRegistryDao().findAll(RegistryConfig.DEAD_TIMEOUT, new Date());
							if (list != null) {
   
								for (XxlJobRegistry item: list) {
   
									
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值