XXL-JOB分布式调度

 一、定时任务简介

  • 定时任务
    • 场景
      • 应用定时给用户发送活动信息,优惠券或支付系统定时清算时
    • 分类
      • 单机
        • 单机的容易实现,但应用于集群环境做分布式部署,就会带来重复执行

        • 解决方案有很多比如加锁、数据库等,但是增加了很多非业务逻辑

        • 常用定时任务

          • Java自带的java.util.Timer类配置比较麻烦,时间延后问题

          • ScheduledExecutorService是基于线程池来进行设计的定时任务类,在这里每个调度的任务都会分配到线程池里的一个线程去执行该任务,并发执行,互不影响

          • SpringBoot框架自带,定时执行的方法加上注解@Scheduled定期执行

      • 分布式
        • 把需要处理的计划任务放入到统一的平台,实现集群管理调度与分布式部署的定时任务 叫做分布式定时任务

        • 支持集群部署、高可用、并行调度、分片处理等

        • 常用定时任务调度器

          • Quartz

            • Quartz关注点在于定时任务而并非是数据,并没有一套根据数据化处理而定的流程

            • 虽然可以实现数据库作业的高可用,但是缺少了分布式的并行调度功能,相对弱点

            • 不支持任务分片、没UI界面管理,并行调度、失败策略等也缺少

          • TBSchedule

            • 这个是阿里早期开源的分布式任务调度系统,使用的是timer而不是线程池执行任务调度,使用timer在处理异常的时候是有缺陷的,但TBSchedule的作业类型比较单一,文档也缺失得比较严重

          • Elastic-job

            • 当当开发的分布式任务调度系统,功能强大,采用的是zookeeper实现分布式协调,具有高可用与分片。

            • 2020年6月,ElasticJob的四个子项目已经正式迁入Apache仓库

            • 由 2 个相互独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成

              • ElasticJob-Lite 定位为轻量级无中心化解决方案,使用jar的形式提供分布式任务的协调服务;

              • ElasticJob-Cloud 使用 Mesos 的解决方案,额外提供资源治理、应用分发以及进程隔离等服务

          • XXL-JOB

            • 大众点评的员工徐雪里在15年发布的分布式任务调度平台,是轻量级的分布式任务调度框架,目标是开发迅速、简单、清理、易扩展; 老版本是依赖quartz的定时任务触发,在v2.1.0版本开始 移除quartz依赖

      对比图
      对比图

二、XXL-JOB简介 

  • xxl-job的设计思想
    • 将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。
    • 将任务抽象成分散的JobHandler,交由“执行器”统一管理
    • “执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。
    • 因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性
  • 架构图
    • 调度中心
      • 负责管理调度的信息,按照调度的配置来发出调度请求
      • 支持可视化、简单的动态管理调度信息,包括新建、删除、更新等,这些操作都会实时生效,同时也支持监控调度结果以及执行日志。
    • 执行器
      • 负责接收请求并且执行任务的逻辑。任务模块专注于任务的执行操作等等,使得开发和维护更加的简单与高效

 

  • XXL-Job具有哪些特性
    • 调度中心HA(中心式):调度采用了中心式进行设计,“调度中心”支持集群部署,可保证调度中心HA

    • 执行器HA(分布式):任务分布式的执行,任务执行器支持集群部署,可保证任务执行HA

    • 触发策略:有Cron触发、固定间隔触发、固定延时触发、API事件触发、人工触发、父子任务触发

    • 路由策略:执行器在集群部署的时候提供了丰富的路由策略,如:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用LFU、最久未使用LRU、故障转移等等

    • 故障转移:如果执行器集群的一台机器发生故障,会自动切换到一台正常的执行器发送任务调度

    • Rolling实时日志的监控:支持rolling方式查看输入的完整执行日志

    • 脚本任务:支持GLUE模式开发和运行脚本任务,包括Shell、python、node.js、php等等类型脚本 

三、spring boot整合xxl-job

  • 启动xxl-job
    • 项目下载地址:https://github.com/xuxueli/xxl-job/releases
    • 目录介绍
      • doc:xxl-job的文档资料,包括了数据库的脚本(后面要用到)

      • xxl-job-core:公共jar包依赖

      • xxl-job-admin:调度中心,项目源码,是Springboot项目,可以直接启动

      • xxl-job-executor-samples:执行器,是Sample实例项目,里面的Springboot工程可以直接启动,也可以在该项目的基础上进行开发,也可以将现有的项目改造成为执行器项目

    • 数据库(本章本集资料或者源码doc/db目录下)
      • xxl_job的数据库里有如下几个表

        • xxl_job_group:执行器信息表,用于维护任务执行器的信息

        • xxl_job_info:调度扩展信息表,主要是用于保存xxl-job的调度任务的扩展信息,比如说像任务分组、任务名、机器的地址等等

        • xxl_job_lock:任务调度锁表

        • xxl_job_log:日志表,主要是用在保存xxl-job任务调度历史信息,像调度结果、执行结果、调度入参等等

        • xxl_job_log_report:日志报表,会存储xxl-job任务调度的日志报表,会在调度中心里的报表功能里使用到

        • xxl_job_logglue:任务的GLUE日志,用于保存GLUE日志的更新历史变化,支持GLUE版本的回溯功能

        • xxl_job_registry:执行器的注册表,用在维护在线的执行器与调度中心的地址信息

        • xxl_job_user:系统的用户表

    • 修改配置文件中的数据库地址以及xxl.job.accessToken

    • 访问地址

      • 地址:ip:8080/xxl-job-admin

      • 默认账号密码:admin / 123456

  • 创建shpingboot项目并启动

    • 引入依赖

      <dependency>
              <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-test</artifactId>
                  <version>2.6.2</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter</artifactId>
                  <version>2.6.2</version>
              </dependency>
              <dependency>
                  <groupId>com.xuxueli</groupId>
                  <artifactId>xxl-job-core</artifactId>
                  <version>2.3.0</version>
              </dependency>
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-web</artifactId>
              <version>2.6.2</version>
      </dependency>
    • 添加配置

      server.port=9001
      spring.application.name=xdclass-job
      #----------xxl-job配置--------------
      #调度中心部署地址,多个配置逗号分隔 "http://address01,http://address02"
      xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
      
      #执行器token,非空时启用 xxl-job, access token
      xxl.job.accessToken=xdclass.net
      
      # 执行器app名称,和控制台那边配置一样的名称,不然注册不上去
      xxl.job.executor.appname=xsagfaf
      
      # [选填]执行器注册:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。
      #从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
      xxl.job.executor.address=
      
      #[选填]执行器IP :默认为空表示自动获取IP(即springboot容器的ip和端口,可以自动获取,也可以指定),多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务",
      xxl.job.executor.ip=
      
      # [选填]执行器端口号:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
      xxl.job.executor.port=9999
      
      #执行器日志文件存储路径,需要对该路径拥有读写权限;为空则使用默认路径
      xxl.job.executor.logpath=./data/logs/xxl-job/executor
      
      #执行器日志保存天数
      xxl.job.executor.logretentiondays=30
    • 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;
      
      @Configuration
      public class XxlJobConfig {
          private Logger log = 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;
      
          //旧版的有bug
          //@Bean(initMethod = "start", destroyMethod = "destroy")
          @Bean
          public XxlJobSpringExecutor xxlJobExecutor() {
              log.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;
          }
      }
  • 去xxl-job控制台添加执行器还有任务

四、高级设置

  • 获取ui见面传递得参数===》String jobParam = XxlJobHelper.getJobParam();
  • 在ui页面日志看到应用得日志答应===》XxlJobHelper.log()
  • 定时任务成功失败决定ui页面执行结果成功与失败===》XxlJobHelper.handleSuccess(),XxlJobHelper.handleFail()
  • 分片任务执行===》根据下面获取分片总节点和当前机器节点,进行id hash 取模 分摊数据到多个分片进行处理
    // 当前分片数,从0开始,即执行器的序号
    int shardIndex = XxlJobHelper.getShardIndex();
    //总分片数,执行器集群总机器数量
    int shardTotal = XxlJobHelper.getShardTotal();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值