• xxl-job 调度中心如何进行进行任务调度


    简介

    再看一遍 xxl-job 架构图:
    在这里插入图片描述
    调度中心主要提供了两个功能: 系统管理 和 任务调度。其余的都是一些辅助功能。

    • 系统管理正如图中所示的那样, 包括任务管理、执行器管理、日志管理。还提供了管理界面。
    • 任务调度就是负责从数据中心拉取任务,并按照执行时间将任务投递给执行器。

    调度器的组成结构

    在这里插入图片描述

    两个核心线程

    当调度中心启动后,会启动以下两个线程:

    1. schedulerThread
      scheudlerThread主要做如下两件事情:
    • 从数据中心(db),也就是 xxl_job_info表中扫描出符合 条件 1 的任务, 条件1 限制如下:
      • 任务执行时间 小于(当前时间 + 5 s)
      • 限制扫描个数, 这个值是动态的,会根据后面的提到的 快慢线程池 中线程数量有关系。
      count = treadpool-size * trigger-qps  (each trigger cost 50ms, qps = 1000/50 = 20) 
      
      treadpool-size = (getTriggerPoolFastMax() + getTriggerPoolSlowMax()) * 20
      // 看完快慢线程池的介绍,再回过头来看这里,会更容易理解  
    • 扫描出来的任务被划分为以下 3 类:
    • 在这里插入图片描述
    1. ringThread

    ringThread的作用就是不断从 容器 中读取 当前时间点需要执行 的任务, 读取出来的任务会交给一个叫 快慢线程池 的东西去将任务传递给调度器去执行。

    时间轮

    上述的 ringThread和 容器 共同组成了一个时间轮。

    简单来讲,时间轮实现了 延迟执行 的功能,它在 xxl-job 中的作用就是让 还未到达执行时间 的任务,按照预计的时间通过 快慢线程池 一个一个送到 执行器 中去执行。

    • 时间轮的数据结构一般是 数组 + 链表, 和 jdk1.7 中的 HashMap 是一个道理,链表中的每个节点就是一个待执行的任务。

    • xxl-job 中的时间轮可以形象描述为以下这张图,像一个只有秒针的钟表一样。

    • ringThread 线程运行过程中,每秒会扫过一个刻度,假设当前刻度位置存在 job 链表,就把链表中的所有 job 取出来,最后丢给 快慢线程池。

    • 当然 xxl-job 为了避免处理耗时太长,会跨过刻度,多向前校验一个刻度;也就是当指针指到 2s 时,会把 1s 和 2s 位置的任务同时读取出来。
      在这里插入图片描述

    快慢线程池

    上面提到任务从数据中心扫描出来后,随之就会被丢到快慢线程池中,快慢线程池的定义如下:

    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());
                        }
                    });
    
            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());
                        }
                    });

    由上可知, 快慢线程池包含了两个线程池 fast 和 slow,当一个 job 提交到快慢线程池后,快慢线程池会根据一些条件, 选择其中一个线程池去执行后续的操作。

    快慢线程池的作用如下:

    实现线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入”Slow”线程池,避免耗尽调度线程,提高系统稳定性;

    什么是慢任务?

    如果一个任务在 1 分钟内,它的执行超时次数超过 10 次,就被归为 慢任务

    当具体的快或者慢线程池接收到调度任务时,会通过 RPC 远程调用去触发 执行器 完成任务的执行逻辑。

    源码入口

    com.xxl.job.admin.core.thread.JobScheduleHelper#start
    
    com.xxl.job.admin.core.thread.JobTriggerPoolHelper#addTrigger
    
    com.xxl.job.core.biz.client.ExecutorBizClient#run

    总结

    本文基于 xxl-job v2.x 的源码分析了 xxl-job 调度器的组成结构 以及 调度中心是如何触发任务的。

    调度器主要包含了以下模块:

    • schedulerThread: 负责从数据中心扫描需要执行的任务
    • ringThread: 负责精准地控制预计需要执行的任务
    • 快慢线程池:通过包装两个线程池,去分别执行 快任务 和 慢任务 的调度过程。

    时间轮附录

    https://www.cnblogs.com/yuarvin/p/14445613.html

  • 相关阅读:
    字符串删减
    iOS-AFNetworking与ASIHTTPRequest的区别
    iOS-清理缓存
    iOS-addSubView时给UIView添加效果
    iOS-明杰解决字段冲突,及数组映射
    iOS-开发将文本复制到剪切板
    iOS-加载html字符串
    iOS-UILabel加线
    iOS-获取webView的高度
    iOS-plist文件的写读
  • 原文地址:https://www.cnblogs.com/yuarvin/p/14445597.html
Copyright © 2020-2023  润新知