xxl-job总结 一(调度器任务调用原理)

本文详细介绍了xxl-job的调度器任务调用原理,从配置启动到任务执行,包括调度线程的启动、任务触发、线程池管理和慢任务处理,最后讲解了如何通过RPC调用执行器执行任务。
摘要由CSDN通过智能技术生成

xxl-job总结 一(任务调用原理)

1、通过XxlJobAdminConfig加载配置,属性配置文件配置完成后执行afterPropertiesSet(),执行XxlJobScheduler.init()方法启动相关配置

@Component
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {
   

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


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

    private XxlJobScheduler xxlJobScheduler;

    /**
     * 调度器启动后,属性配置文件配置完成后执行
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
   
        adminConfig = this;
        //初始化任务执行
        xxlJobScheduler = new XxlJobScheduler();
        xxlJobScheduler.init();
    }

2、JobScheduleHelper.getInstance().start(); 启动调度器

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


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

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

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

        // admin lose-monitor run
        JobLosedMonitorHelper.getInstance().start();

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

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

        // start-schedule 启动调度器
        JobScheduleHelper.getInstance().start();

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

3、启动调度线程、时间轮环形线程;过期5s内,立即触发一次执行JobTriggerPoolHelper.trigger(),当前时间开始计算下次触发时间;

	/**
 * 调度器
 * 死循环,在xxl_job_info表里取将要执行的任务,更新下次执行时间的,调用JobTriggerPoolHelper类,来给执行器发送调度任务的
 * @author xuxueli 2019-05-21
 */
public class JobScheduleHelper {
   
    private static Logger logger = LoggerFactory.getLogger(JobScheduleHelper.class);

    private static JobScheduleHelper instance = new JobScheduleHelper();
    public static JobScheduleHelper getInstance(){
   
        return instance;
    }

    public static final long PRE_READ_MS = 5000;    // pre read

    /**
     * 调度线程
     */
    private Thread scheduleThread;
    /**
     * 时间轮环形线程
     */
    private Thread ringThread;
    private volatile boolean scheduleThreadToStop = false;
    private volatile boolean ringThreadToStop = false;
    /**
     * ringData是以0到59的整数为key,以jobId集合为value的Map集合
     */
    private volatile static Map<Integer, List<Integer>> ringData = new ConcurrentHashMap<>();

    public void start(){
   

        // schedule thread
        scheduleThread = new Thread(new Runnable() {
   
            @Override
            public void run() {
   

                try {
   
                    TimeUnit.MILLISECONDS.sleep(5000 - System.currentTimeMillis()%1000 );
                } catch (InterruptedException e) {
   
                    if (!scheduleThreadToStop) {
   
                        logger.error(e.getMessage(), e);
                    }
                }
                logger.info(">>>>>>>>> init xxl-job admin scheduler success.");

                // pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)
                int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20;

                while (!scheduleThreadToStop) {
   

                    // Scan Job
                    long start = System.currentTimeMillis();

                    Connection conn = null;
                    Boolean connAutoCommit = null;
                    PreparedStatement preparedStatement = null;

                    boolean preReadSuc = true;
                    try {
   

                        conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();
                        connAutoCommit = conn.getAutoCommit();
                        conn.setAutoCommit(false);
                        //利用for update语句进行获取任务的资格锁定,再去获取未来5秒内即将要执行的任务
                        preparedStatement = conn.prepareStatement(  "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );
                        preparedStatement.execute();

                        // tx start

                        // 1、pre read ->预读5s内调度任务
                        long nowTime = System.currentTimeMillis();
                        List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);
                        if (scheduleList!=null && scheduleList.size()>0) {
   
                            // 2、push time-ring ->推送时间轮
                            for (XxlJobInfo jobInfo: scheduleList) {
   

                                // time-ring jump
                                // 时间轮刻度计算->当前时间大于(下一次调度时间+5s)
                                if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {
   
                                    // 过期超5s:本地忽略,当前时间开始计算下次触发时间
                                    // 2.1、trigger-expire > 5s:pass && make next-trigger-time
                                    logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());
                                    // fresh next->根据Cron表达式,获得下一次调度时间
                                    refreshNextValidTime(jobInfo, new Date());

                                } else if (nowTime > jobInfo.getTriggerNextTime()) {
   
                                    // 过期5s内 :立即触发一次,当前时间开始计算下次触发时间;
                                    // 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time

                                    // 1、trigger -> 立即执行
                                    JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null, null);
                                    logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );

                                    // 2、fresh next ->刷新下一次调度时间
       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值