XXL-JOB快速入门

文章目录


前言

XXL-JOB 是一款分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。基于 Java 语言实现,主要用于解决分布式系统中任务调度的一致性、可靠性和可扩展性问题。它具有轻量级、易集成、功能丰富等特点,广泛应用于微服务、分布式系统中的定时任务、批量处理、数据同步等场景。

官网:https://www.xuxueli.com/xxl-job/

定时任务实现方式

Timer

java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少

ScheduledExecutorService

jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。

Spring Task

Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多。

Quartz

之前用的比较多,配置起来复杂,不支持分片,没用界面。

以上定时任务存在的问题

1.执行一次

如果想让它马上执行一次,这个时候可能就需要额外再写一个Rest接口或者再另外写一个单独的Job

2.更改执行时间

得修改代码,提交测试,然后打包上线

3.暂停任务

比如一些定时报警的需求,当报警突然变得很多,这个时候需要暂停一下让其停止发送警。

我们可以用配置的开关去做,再逻辑中判断定时任务开关是否打开来做。这样做虽然也比较简单,但是我们这样需要新添加一些与任务无关的逻辑

4.监控

没有管理界面,不方便查看任务执行情况

5.分片执行

单台服务处理大数据量数据时间太长、效率低下,需要其他机器协同执行

解决方案XXL-JOB

支持任务分片

文档完善

提供管理台

接入简单

弹性扩容

...

分片原理

架构图

代码案例

1.git拉去代码

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

Gitee: https://gitee.com/xuxueli0323/xxl-job/

2.数据库表初始化

执行以下sql文件

3.启动xxl-job-admin项目

修改数据库连接相关配置

启动成功后进入前台

127.0.0.1:8080/xxl-job-admin

admin/123456

4.搭建demo

启动xxl-job-executor-sample-springboot或新建一个demo

1.pom依赖

xml 复制代码
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.7.RELEASE</version>
  <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
  <dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.2.0</version>
  </dependency>
</dependencies>

2.配置文件

yml 复制代码
server:
  port: 8190
  servlet:
    context-path: /lc
spring:
  application:
    name: qf-xxl-job-demo0

xxl:
  job:
    admin:
      addresses: http://127.0.0.1:8080/xxl-job-admin
    accessToken: default_token
    executor:
      appname: qf-xxl-job-demo
      address: ""
      ip: 127.0.0.1
      port: 9910
      logpath: D:\files\log
      logretentiondays: 10

如果想要实现集群下执行定时任务,需要配置不同的xxl.job.executor.port和spring.application.name。但是注意需要配置相同的xxl.job.executor.appname。

如:

xml 复制代码
server:
  port: 8191
  servlet:
    context-path: /
spring:
  application:
    name: qf-xxl-job-demo1
xxl:
  job:
    admin:
      addresses: http://127.0.0.1:8080/xxl-job-admin
    accessToken: default_token
    executor:
      appname: qf-xxl-job-demo
      address: ""
      ip: 127.0.0.1
      port: 9911
      logpath: D:\files\log
      logretentiondays: 10

3.配置类

java 复制代码
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * xxl-job config
 *
 * @author xuxueli 2017-04-28
 */
@Configuration
public class XxlJobConfig {
    private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);

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

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

//    @Value("${xxl.job.admin.timeout}")
//    private int timeout;

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

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

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

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

    @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.setAddress(address);
        xxlJobSpringExecutor.setIp(ip);
        xxlJobSpringExecutor.setPort(port);
        xxlJobSpringExecutor.setAccessToken(accessToken);
//        xxlJobSpringExecutor.setTimeout(timeout);
        xxlJobSpringExecutor.setLogPath(logPath);
        xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);

        return xxlJobSpringExecutor;
    }

    /**
     * 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
     *
     *      1、引入依赖:
     *          <dependency>
     *             <groupId>org.springframework.cloud</groupId>
     *             <artifactId>spring-cloud-commons</artifactId>
     *             <version>${version}</version>
     *         </dependency>
     *
     *      2、配置文件,或者容器启动变量
     *          spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
     *
     *      3、获取IP
     *          String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
     */
}

4.启动类

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

5.任务

java 复制代码
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.util.ShardingUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class TestJob {


    @XxlJob("helloWorld")
    public ReturnT<String> helloWorld(String param) {
        ShardingUtil.ShardingVO shardingVo = ShardingUtil.getShardingVo();
        int total = shardingVo.getTotal();//分片总数
        int index = shardingVo.getIndex();//当前分片索引
        log.info("分片总数:{},当前分片索引:{}",total,index);
        XxlJobLogger.log("XXL-JOB, updateSilentExecStatus beginning");
        System.out.println("XXL-JOB===============================Hello World-0,param"+param);
        return ReturnT.SUCCESS;
    }

    /**
     * 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
     */
    @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
    public ReturnT<String> demoJobHandler2(String param) throws Exception {
        log.info("XXL-JOB, Hello World.");
        return ReturnT.SUCCESS;
    }
    public void init(){
        log.info("init");
    }
    public void destroy(){
        log.info("destroy");
    }
}

启动项目

6.新增执行器

AppName就是在配置文件中的xxl.job.executor.appname = qf-xxl-job-demo

启动项目后可以在执行器管理看到对应的服务

7.创建任务

当执行器注册成功后创建任务

  • 执行器:选择我们刚上一步创建的执行器。
  • 任务描述: 随便写下这个任务主要是做什么的。
  • 负责人:测试环境就只有一个admin可选,生产环境可指定具体的负责人。
  • 调度类型: 选择默认CRON,其他还有一个无和固定速度,顾名思义无就是不执行,固定速度就是每隔多少秒就执行一次。
  • Cron: cron表达式,不知道怎么写的可以点击右边的编辑按钮,直接选择时间。
  • 运行模式:分为BEAN和GLUE两种,BEAN就是javabean,自定义执行函数,GLUE就是将任务代码直接"贴到"调度系统中执行。这里我们选择默认的BEAN即可,在业务代码中实现具体逻辑。
  • JobHandler: 具体要执行的任务函数。
  • 任务参数:下发到执行器任务函数的参数,这里我们可以填写一些需要发送的用户和内容。

添加完之后在操作点击启动,即可执行定时任务


相关推荐
MacroZheng5 小时前
别再用 BeanUtils 了,这款 PO VO DTO 转换神器不香么?
java·spring boot·后端
AAA修煤气灶刘哥5 小时前
从 “库存飞了” 到 “事务稳了”:后端 er 必通的分布式事务 & Seata 闯关指南
java·后端·spring cloud
一刻缱绻5 小时前
iptables MASQUERADE规则对本地回环地址的影响分析
后端·tcp/ip
码事漫谈6 小时前
Hello World背后的秘密:详解 C++ 编译链接模型
后端
brzhang6 小时前
现在有一种深深的感觉,觉大多数情况下,多 Agent 不如单 Agent 好
前端·后端·架构
码事漫谈6 小时前
C++ 类型系统浅析:值类别与引用类型
后端
shark_chili6 小时前
程序员必读:CPU运算原理深度剖析与浮点数精度问题实战指南
后端
Java中文社群6 小时前
崩了!Nacos升级到3.0竟不能用了,哭死!
java·后端
Goboy6 小时前
你刷网页的一瞬间,背后服务器在"排队抢活儿"?
后端·面试·架构