1.定时计算任务

2.使用传统的springboot中的定时任务调度@Schedule,会出现的问题

  1. 做集群任务的重复执行问题
  2. cron表达式定义在代码之中,修改不方便
  3. 定时任务失败了,无法重试也没有统计
  4. 如果任务量过大,不能有效的分片执行(如果任务量过大,只用一台机器执行,会很慢)

3.什么是分布式任务调度

如发放5000张优惠券,单体架构使用@Schedule是没问题的

但是分布式应用会出现问题,如果有两个优惠券服务集群,且是使用@schudele,两个微服务都会去执行这个定时任务,最终总计发1w张优惠券

解决方法:

  1. 使用redis的分布式锁解决(谁抢占到这个定时任务谁执行)
  2. 使用zookeeper的主从策略,让某个微服务执行发放

这两个方法共同的缺点:耦合度高

4.使用xxl-job解决分布式任务调度

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。

源码地址:https://gitee.com/xuxueli0323/xxl-job

文档地址:https://www.xuxueli.com/xxl-job/

5.XXL-Job-环境搭建

  1. 调度中心环境要求     Maven3+     Jdk1.8+     Mysql5.7+
  2. 源码仓库地址

源码仓库地址

Release Download

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

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

http://gitee.com/xuxueli0323/xxl-job 

http://gitee.com/xuxueli0323/xxl-job/releases 

6.XXL-Job(源码说明)

7.配置部署调度中心

作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。

  1. 调度数据库初始化SQL脚本执行    位置:xxl-job/doc/db/tables_xxl_job.sql  共8张表
  2. 调度中心配置   配置文件位置:                                                                                            xxl-job/xxl-jobadmin/src/main/resources/application.properties                                                 修改数据库账号密码
  3. 启动XXLJobAdminApplication
  4. 启动调度中心,任务调度中心  默认登录账号 “admin/123456”, 登录后运行界面如下图所示。

8.docker上安装和部署xxl-job

配置部署调度中心-docker安装

1.创建mysql容器,初始化xxl-job的SQL脚本

docker run -p 3306:3306 --name mysql57 \
-v /opt/mysql/conf:/etc/mysql \
-v /opt/mysql/logs:/var/log/mysql \
-v /opt/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=root \
-d mysql:5.7

datagrip连接低版本的MySQL会有问题,这里需要修改一下,设置useSSL = false(不使用SSL加密,因为低版本的MySQL不支持SSL加密)

改成useSSL=false

2.拉取镜像

docker pull xuxueli/xxl-job-admin:2.3.0

3.创建容器

-e PARAMS= 表示要连接的数据库

-p 8888:8080 -v /tmp:/data/applogs \  表示原本服务端口是8080,映射到了docker的8888上面

docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.200.130:3306/xxl_job?Unicode=true&characterEncoding=UTF-8 \
--spring.datasource.username=root \
--spring.datasource.password=root" \
-p 8888:8080 -v /tmp:/data/applogs \
--name xxl-job-admin --restart=always  -d xuxueli/xxl-job-admin:2.3.0

9.xxl-job入门案例编写

1. 登录调度中心,点击下图所示“新建任务”按钮,新建示例任务

JobHandler指定某个方法执行

2. 创建xxljob-demo项目,导入依赖
<dependencies>
    <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.3.0</version>
    </dependency>
</dependencies>
3 application.yml配置
server:
  port: 8881


xxl:
  job:
    admin:
      #调度中心地址
      addresses: http://192.168.200.130:8888/xxl-job-admin
    executor:
      #执行器名称
      appname: xxl-job-executor-sample
      #实例端口,多个实例不要重复
      port: 9999
4.新建配置类

@ValueSpring 框架中的一个核心注解,用于从配置文件(如 application.ymlapplication.properties)中读取属性值,并注入到 Spring Bean 的字段中

package com.heima.xxljob.config;

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.executor.appname}")
    private String appname;

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


    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        logger.info(">>>>>>>>>>> xxl-job config init.");
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
//     指定调度中心,也就是xxl-job-admin的地址
        xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
//     指定执行器名称
        xxlJobSpringExecutor.setAppname(appname);
//     指定任务端口,每个任务端口不能重复(多个节点端口不重复)
        xxlJobSpringExecutor.setPort(port);
        return xxlJobSpringExecutor;
    }


}
5.任务代码,重要注解:@XxlJob(“JobHandler”)

JobHandler指的是控制台中任务的JobHandler的名称,用于在Java代码中指定要执行的方法

JobHandler指定某个方法执行

在控制台中设置的JobHandler为demoJobHandler,所以这里方法上也是。

某个被spring管理的bean方法上加上@XxlJob注解,指定要执行的调度任务

package com.heima.xxljob.job;

import com.xxl.job.core.handler.annotation.XxlJob;
import org.springframework.stereotype.Component;

//一定要交给Spring容器管理,才能执行分布任务调度
@Component
public class HelloJob {


    @XxlJob("demoJobHandler")
    public void helloJob(){
        System.out.println("简单任务执行了。。。。");

    }
}
6.测试-单节点
  • 启动微服务

  • 在xxl-job的调度中心中启动任务

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐