快速入门 XXL-JOB

2024-10-29 14:44

示例代码对应仓库:lab-28-task-xxl-job 。

虽然说,Quartz 的功能,已经能够满足我们对定时任务的诉求,但是距离生产可用、好用,还是有一定的距离。在最早开始实习的时候,因为Quartz 只提供了任务调度的功能,不提供管理任务的管理与监控控制台,需要自己去做二次封装。当时,因为社区中找不到合适的实现这块功能的开源项目,所以我们就自己进行了简单的封装,满足我们的管理与监控的需求。

不过现在呢,开源社区中已经有了很多优秀的调度任务中间件。其中,比较有代表性的就是 XXL-JOB 。其对自己的定义如下:

XXL-JOB 是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。

对于 XXL-JOB 的入门,已经在 《芋道 XXL-JOB 极简入门》 中编写,胖友先跳转到该文章阅读。重点是,要先搭建一个 XXL-JOB 调度中心。😈 因为,本文我们是来在 Spring Boot 项目中,实现一个 XXL-JOB 执行器。

引入依赖

在 pom.xml 文件中,引入相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>
<artifactId>lab-28-task-xxl-job</artifactId>
 
<dependencies>
    <!-- 实现对 Spring MVC 的自动化配置 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
 
    <!-- XXL-JOB 相关依赖 -->
    <dependency>
        <groupId>com.xuxueli</groupId>
        <artifactId>xxl-job-core</artifactId>
        <version>2.1.1</version>
    </dependency>
</dependencies>
</project>

具体每个依赖的作用,胖友自己认真看下添加的所有注释噢。比较可惜的是,目前 XXL-JOB 官方并未提供 Spring Boot Starter 包,略微有点尴尬。不过,社区已经有人在提交 Pull Request 了,详细可见 https://github.com/xuxueli/xxl-job/pull/820 。

应用配置文件

在 application.yml 中,添加 Quartz 的配置,如下:

server:
  port: 9090 #指定一个端口,避免和 XXL-JOB 调度中心的端口冲突。仅仅测试之用
 xxl-job
xxl:
  job:
    admin:
      addresses: http://127.0.0.1:8080/xxl-job-admin # 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
    executor:
      appname: lab-28-executor # 执行器 AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
      ip: # 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
      port: 6666 # ## 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
      logpath: /Users/yunai/logs/xxl-job/lab-28-executor # 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
      logretentiondays: 30 # 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
    accessToken: yudaoyuanma # 执行器通讯TOKEN [选填]:非空时启用;
  • 具体每个参数的作用,胖友自己看下详细的注释哈。

XxlJobConfiguration

在 cn.iocoder.springboot.lab28.task.config 包路径下,创建 DataSourceConfiguration 类,配置 XXL-JOB 执行器。代码如下:

// XxlJobConfiguration.java

@Configuration
public class XxlJobConfiguration {
    @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() {
        // 创建 XxlJobSpringExecutor 执行器
        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;
    }
}
  • 在 #xxlJobExecutor() 方法,创建了 Spring 容器下的 XXL-JOB 执行器 Bean 对象。要注意,方法上添加了的 @Bean 注解,配置了启动和销毁方法。

DemoJob

在 cn.iocoder.springboot.lab28.task.job 包路径下,创建 DemoJob 类,示例定时任务类。代码如下:

// DemoJob.java

@Component
@JobHandler("demoJob")
public class DemoJob extends IJobHandler {
    private Logger logger = LoggerFactory.getLogger(getClass());

    private final AtomicInteger counts = new AtomicInteger();

    @Override
    public ReturnT<String> execute(String param) throws Exception {
        // 打印日志
        logger.info("[execute][定时第 ({}) 次执行]", counts.incrementAndGet());
        // 返回执行成功
        return ReturnT.SUCCESS;
    }
}
  • 继承 XXL-JOB IJobHandler 抽象类,通过实现 #execute(String param) 方法,从而实现定时任务的逻辑。

  • 在方法上,添加 @JobHandler 注解,设置 JobHandler 的名字。后续,我们在调度中心的控制台中,新增任务时,需要使用到这个名字。

#execute(String param) 方法的返回结果,为 ReturnT 类型。当返回值符合 “ReturnT.code == ReturnT.SUCCESS_CODE” 时表示任务执行成功,否则表示任务执行失败,而且可以通过 “ReturnT.msg” 回调错误信息给调度中心;从而,在任务逻辑中可以方便的控制任务执行结果。

#execute(String param) 方法的方法参数,为调度中心的控制台中,新增任务时,配置的“任务参数”。一般情况下,不会使用到。

Application

创建 Application.java 类,配置 @SpringBootApplication 注解即可。代码如下:

// Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

运行 Application 类,启动示例项目。输出日志精简如下:

 XXL-JOB 启动日志
2019-11-29 00:58:42.429  INFO 46957 --- [           main] c.xxl.job.core.executor.XxlJobExecutor   : >>>>>>>>>>> xxl-job register jobhandler success, name:demoJob, jobHandler:cn.iocoder.springboot.lab28.task.job.DemoJob@3af9aa66
2019-11-29 00:58:42.451  INFO 46957 --- [           main] c.x.r.r.provider.XxlRpcProviderFactory   : >>>>>>>>>>> xxl-rpc, provider factory add service success. serviceKey = com.xxl.job.core.biz.ExecutorBiz, serviceBean = class com.xxl.job.core.biz.impl.ExecutorBizImpl
2019-11-29 00:58:42.454  INFO 46957 --- [           main] c.x.r.r.provider.XxlRpcProviderFactory   : >>>>>>>>>>> xxl-rpc, provider factory add service success. serviceKey = com.xxl.job.core.biz.ExecutorBiz, serviceBean = class com.xxl.job.core.biz.impl.ExecutorBizImpl
2019-11-29 00:58:42.565  INFO 46957 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2019-11-29 00:58:42.629  INFO 46957 --- [       Thread-7] com.xxl.rpc.remoting.net.Server          : >>>>>>>>>>> xxl-rpc remoting server start success, nettype = com.xxl.rpc.remoting.net.impl.netty_http.server.NettyHttpServer, port = 6666

此时,因为我们并未在 XXL-JOB 调度中心进行相关的配置,所以 DemoJob 并不会执行。下面,让我们在 XXL-JOB 调度中心进行相应的配置。

新增执行器

浏览器打开 http://127.0.0.1:8080/xxl-job-admin/jobgroup 地址,即「执行器管理」菜单。如下图:

img

点击「新增执行器」按钮,弹出「新增执行器」界面。如下图:

img

填写完 "lab-28-executor" 执行器的信息,点击「保存」按钮,进行保存。耐心等待一会,执行器会自动注册上来。如下图:

img

  • 执行器列表中显示在线的执行器列表, 可通过 "OnLine 机器" 查看对应执行器的集群机器。

    相同执行器,有且仅需配置一次即可。

新建任务

浏览器打开 http://127.0.0.1:8080/xxl-job-admin/jobinfo 地址,即「任务管理」菜单。如下图:

img

点击最右边的「新增」按钮,弹出「新增」界面。如下图:

img

填写完 "demoJob" 任务的信息,点击「保存」按钮,进行保存。如下图:

img

点击 "demoJob" 任务的「操作」按钮,选择「启动」,确认后,该 "demoJob" 任务的状态就变成了 RUNNING 。如下图:

img

此时,我们打开执行器的 IDE 界面,可以看到 DemoJob 已经在每分钟执行一次了。日志如下:

2019-11-29 01:30:00.161  INFO 48374 --- [      Thread-18] c.i.springboot.lab28.task.job.DemoJob    : [execute][定时第 (1) 次执行]
2019-11-29 01:31:00.012  INFO 48374 --- [      Thread-18] c.i.springboot.lab28.task.job.DemoJob    : [execute][定时第 (2) 次执行]
2019-11-29 01:32:00.009  INFO 48374 --- [      Thread-18] c.i.springboot.lab28.task.job.DemoJob    : [execute][定时第 (3) 次执行]
2019-11-29 01:33:00.010  INFO 48374 --- [      Thread-18] c.i.springboot.lab28.task.job.DemoJob    : [execute][定时第 (4) 次执行]
2019-11-29 01:34:00.005  INFO 48374 --- [      Thread-18] c.i.springboot.lab28.task.job.DemoJob    : [execute][定时第 (5) 次执行]

并且,我们在调度中心的界面上,点击 "demoJob" 任务的「操作」按钮,选择「查询日志」,可以看到相应的调度日志。如下图:

img

至此,我们已经完成了 XXL-JOB 执行器的入门。

相关文章
热点文章
精彩视频
Tags

站点地图 在线访客: 今日访问量: 昨日访问量: 总访问量: