xxl-job的使用及原理分析

xxl-job是一个任务调度平台,能够设置调度的策略。相对于之前spring 提供的@Sheduel,xxl-job能够支持分布式调度,提供了很多方便、易用的功能,下面会详细介绍它的使用和原理
xxl-job整体框架分为两个部分调度中心和执行器,先来了解它的使用部分

如何使用

从码云中下载xxl-job项目 https://gitee.com/xuxueli0323/xxl-job
在这里插入图片描述

调度中心启动

admin模块为调度中心,从doc文件夹下获取数据库的建表sql,在数据库中执行后将数据库的连接配置在application.properties中,启动项目
浏览器中访问地址:http://localhost:8080/xxl-job-admin
在这里插入图片描述
输入默认用户名 admin、密码 123456 登录
在这里插入图片描述

执行器的启动

执行器一般是集成在项目中,在项目中引入依赖

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.4.0</version>
</dependency>

设置配置信息

logging:
#配置日志格式信息
  config: classpath:logback.xml
xxl:
 job:
  executor:
  #执行器应用名称、ip、port
   appname: xxl-job-executor-helloword
   ip: localhost
   port: 8071
   # 存放日志的配置文件
   logpath: /data/applogs/xxl-job/jobhandler
   # 日志文件存储时间,超过设置时间会清除
   logretentiondays: 3
   #设置 通信accessToken
  accessToken: default_token
  admin:
  #设置 调度中心的地址
   addresses: http://127.0.0.1:8080/xxl-job-admin

解析配置信息

@Configuration
//指定任务Handler所在包路径
@ComponentScan(basePackages = "com.person.xxlJob.executor")
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    @Value("${xxl.job.executor.appname}")
    private String appName;

    @Value("${xxl.job.executor.ip}")
    private String ip;

    @Value("${xxl.job.executor.port}")
    private int port;

    @Value("${xxl.job.accessToken}")
    private String accessToken;

    @Value("${xxl.job.executor.logpath}")
    private String logPath;

    @Value("${xxl.job.executor.logretentiondays}")
    private int logRetentionDays;


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info("====xxl-job config init====");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
        xxlJobSpringExecutor.setAppname(appName);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
        return xxlJobSpringExecutor;
    }

}

任务设置

@Component
public class DemoJobHandler{

    /**
     * 1、简单任务示例(Bean模式)
     */
    @XxlJob("demoJobHandler")
    public void demoJobHandler() throws Exception {
        XxlJobHelper.log("XXL-JOB, Hello World.");

        for (int i = 0; i < 5; i++) {
            XxlJobHelper.log("beat at:" + i);
            TimeUnit.SECONDS.sleep(2);
        }
        // default success
    }

}

启动项目后,查看调度中心注册的执行器
需要手动添加执行器的分组信息
在这里插入图片描述
在执行器发送心跳信息后,就可查看注册的执行器信息
点击查看,可以看到注册的执行器列表
在这里插入图片描述

新增任务执行

在这里插入图片描述
启动任务后可以查看调度日志信息
在这里插入图片描述

原理分析

我们先看下官方的架构图
在这里插入图片描述

执行器注册过程

执行器启动时首先会注册地址信息到调度中心,调度中心执行任务时才能有执行器去执行
从xxl-job配置类入手,从前面的配置中可以看到定义了类XxlJobSpringExecutor,查看这个类实现了接口SmartInitializingSingleton,项目启动时在所有类实例化后会调用接口的实现方法afterSingletonsInstantiated

public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationContextAware, SmartInitializingSingleton, DisposableBean {
    private static final Logger logger = LoggerFactory.getLogger(XxlJobSpringExecutor.class);
    private static ApplicationContext applicationContext;

    public XxlJobSpringExecutor() {
    }

    public void afterSingletonsInstantiated() {
        this.initJobHandlerMethodRepository(applicationContext);
        GlueFactory.refreshInstance(1);

        try {
        //查看父类的方法
            super.start();
        } catch (Exception var2) {
            throw new RuntimeException(var2);
        }
    }
    ...
}
//父类XxlJobExecutor中的start()方法,可以看见服务ip、port的信息
public void start() throws Exception {
    XxlJobFileAppender.initLogPath(this.logPath);
    this.initAdminBizList(this.adminAddresses, this.accessToken);
    JobLogFileCleanThread.getInstance().start((long)this.logRetentionDays);
    TriggerCallbackThread.getInstance().start();
    //这个方法实现 服务的注册
    this.initEmbedServer(this.address, this.ip, this.port, this.appname, this.accessToken);
}
//最后在类AdminBizClient中查看具体的调用信息
 public ReturnT<String> registry(RegistryParam registryParam) {
    return XxlJobRemotingUtil.postBody(this.addressUrl + "api/registry", this.accessToken, this.timeout, registryParam, String.class);
}

任务调度执行的过程

查看Admin中的配置类XxlJobAdminConfig ,实现了接口InitializingBean,在类初始化时会调用接口的实现方法

@Component
public class XxlJobAdminConfig implements InitializingBean, DisposableBean {

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

    @Override
    public void afterPropertiesSet() throws Exception {
        adminConfig = this;
        xxlJobScheduler = new XxlJobScheduler();
        //调用init方法时,会执行设置的任务
        xxlJobScheduler.init();
    }
    ...//其他代码没有复制,省略
   }
   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.");
    }
...
}
    

调度线程会将任务放到时间轮中,根据设置的规则定时调度任务,调度任务选择执行器时根据路由策略选择执行器,执行器执行完成任务后,将任务结果发送到调度中心

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值