使用分布式任务调度平台xxl-job

使用分布式任务调度平台xxl-job

一.下载源码

https://github.com/xuxueli/xxl-job/releases

二.准备环境

  1. 在MySQL5.6+上执行源码目录下\doc\db\tables_xxl_job.sql脚本(脚本中初始化了一个账户,一个执行器)
  2. 使用idea导入源码目录下\xxl-job-admin的maven项目
  3. 修改\xxl-job-admin(下面简称admin)项目application.properties中数据库配置,改为自己本地
  4. admin是基于Springboot,按照Springboot方式即可启动。
  5. 根据application.properties的配置,默认访问地址为127.0.0.1:8080/xxl-job-admin,默认账目密码为admin/123456

三.接入调度任务

xxl-job采用调度与任务分离的模式,分为两块:调度中心(admin),任务(executor).上面启动的即为admin,admin负责调度任务,控制任务的触发时机以及路由策略。executor负责具体要执行的业务,即任务代码写在executor中。而工作中一般业务写在service层,所以可以将executor接入到service层,然后将任务代码写到executor。下例中使用无框架的方式演示接入executor。

1.新建一个简单maven项目,导入使用xxljob需要的包

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

2.创建executor配置类(使executor注册业务到admin)

 1 public class XxljobConfig {
 2 
 3     private static final String ADMIN_ADDRESSES = "http://127.0.0.1:8080/xxl-job-admin";
 4     private static final String EXECUTOR_APPNAME = "txxljob"; // EXECUTOR_APPNAME需要先到admin配置
 5 
 6     private static XxlJobExecutor xxlJobExecutor;
 7 
 8     static {
 9         // 实例化,此处仅配置了最基本的参数
10         xxlJobExecutor = new XxlJobExecutor();
11         xxlJobExecutor.setAdminAddresses(ADMIN_ADDRESSES);
12         xxlJobExecutor.setAppName(EXECUTOR_APPNAME);
13     }
14 
15     public static void start(int port) {
16 
17         // 注册需要调度的业务
18         initRegister(port);
19 
20         // 启动(注册到调度中心)
21         try {
22             xxlJobExecutor.setPort(port);
23             xxlJobExecutor.start();
24             System.out.println("xxljob成功注册到调度中心");
25         } catch (Exception e) {
26             e.printStackTrace();
27         }
28     }
29 
30     public static void destory() {
31         if (null != xxlJobExecutor)
32             xxlJobExecutor.destroy();
33     }
34 
35     private static void initRegister(int port) {
36         XxlJobExecutor.registJobHandler("XxljobDemoService", new XxljobDemoService(port)); // 注册任务代码到admin
37     }
38 
39 }

注意上面代码中EXECUTOR_APPNAME = "txxljob",需要先到admin中配置一个AppName为txxljob的执行器。可以将EXECUTOR_APPNAME看做是执行器的唯一标识,admin调度任务时先根据执行器找任务。

3.创建一个简单的任务,让调度中心调度

 1 public class XxljobDemoService extends IJobHandler {
 2 
 3     private final int port;
 4 
 5     public XxljobDemoService(int port) {
 6         this.port = port;
 7     }
 8 
 9     public ReturnT<String> execute(String s) {
10         System.out.println("demo业务" + port +"被调度中心调度");
11         return SUCCESS;
12     }
13 }

注意:2中XxljobConfig中XxlJobExecutor.registJobHandler("XxljobDemoService", new XxljobDemoService(port))将XxljobDemoService注册到调度中心。

4.创建两个启动类,模拟分布式环境

 1 public class App1 {
 2 
 3     public static void main(String[] args) throws InterruptedException {
 4         XxljobConfig.start(9994);
 5         while (true) {
 6             TimeUnit.HOURS.sleep(1);
 7         }
 8     }
 9 
10 }
 1 public class App2 {
 2 
 3     public static void main(String[] args) throws InterruptedException {
 4         XxljobConfig.start(9995);
 5         while (true) {
 6             TimeUnit.HOURS.sleep(1);
 7         }
 8     }
 9 
10 }

5.分别启动App1和App2,将会注册两个实例到admin中

四.在admin中配置任务的执行规则以及策略

* 执行器:选中上面配置的自定义执行新txxljob(因为executor注册时使用的是此执行器)

* 路由策略:由于注册了两个实例到admin,所以这里选择轮询,让两个实例都能得到执行,也可以选择其他的路由策略

* 运行模式:BEAN是本文中使用的运行模式,即将业务代码写到独立于admin的项目中,然后注册到admin中。xxljob也支持在admin平台页面中直接写业务代码的方式。

* Cron:即普通的cron表达式,控制任务的触发时机

* JobHandler:可以看做是任务的索引,与代码中保持一致

 五.启动四中配置的任务,观察executor被调度情况

 观察App1和App2控制台输出如下,说明admin可以正常调度App1和App2中的任务,接入完成。