xxl-job详解

news2024/11/26 10:18:59

什么是xxl-job?

​ xxl-job是一个分布式的任务调度平台,其核心设计目标是:学习简单、开发迅速、轻量级、易扩展,现在已经开放源代码并接入多家公司的线上产品线,开箱即用。xxl是xxl-job的开发者大众点评的许雪里名称的拼音开头。

​ xxl-job框架主要用于处理分布式的定时任务,其主要由调度中心和执行器组成。

  • 调度模块(调度中心)
    负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块;
    支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。
  • 执行模块(执行器)
    负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;
    接收“调度中心”的执行请求、终止请求和日志请求等。

总结:

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

​ 执行器:接收调度中心的调度并且执行,可以直接执行也可以集成到项目中。

​ 调度中心和执行器两个模块分开部署,相互分离,两者之间通过RPC进行通信,其中调度中心主要是提供一个平台,管理调度信息,发送调度请求,自己不承担业务代码,而执行器接受调度中心的调度执行业务逻辑。

输入图片说明

xxl-job的原理

  1. 执行器的注册和发现

    执行器的注册和发现主要是关系两张表:

    xxl_job_registry:执行器的实例表,保存实例信息和心跳信息,xxl_job_group:每个服务注册的实例列表。

    执行器启动线程每隔30秒向注册表xxl_job_registry请求一次,更新执行器的心跳信息,调度中心启动线程每隔30秒检测一次xxl_job_registry,将超过90秒还没有收到心跳的实例信息从xxl_job_registry删除,并更新xxl_job_group服务的实例列表信息。

  2. 调度中心调用执行器

    调度中心的操作:

    调度中心通过循环不停的:

    1. 关闭自动提交事务

    2. 利用mysql的悲观锁,其他事务无法进入

      select * from xxl_job_lock where lock_name = 'schedule_lock' for update
      
    3. 读取数据库中的xxl_job_info:记录定时任务的相关信息,该表中有trigger_next_time字段表示下一次任务的触发时间。拿到距离当前时间5s内的任务列表,分为三种情况处理:

      • 对于当前时间-任务的下一次触发时间>5,直接调过不执行,重置trigger_next_time的时间。(超过5s)

      • 对于任务的下一次触发时间<当前时间<任务的下一次触发时间+5的任务(不超过5s的):

        1. 开线程处理执行触发逻辑,根据当前时间更新下一次任务触发时间

        2. 如果新的任务下一次触发时间-当前时间<5,放到时间轮中,时间轮是一个map:

            private volatile static Map<Integer, List<Integer>> ringData = new ConcurrentHashMap<>();
          
        3. 根据新的任务下一次触发时间更新下下一次任务触发时间

      • 对于任务的下一次触发时间>当前时间,将其放入时间轮中,根据任务下一次触发时间更新下下一次任务触发时间

    4. commit提交事务,同时释放排他锁

    执行器的操作:

    1. 执行器接收到调度中心的调度信息,将调度信息放到对应的任务的等待队列中
    2. 执行器的任务处理线程从任务队列中取出调度信息,执行业务逻辑,将结果放入一个公共的等待队列中(每个任务都有一个单独的处理线程和等待队列,任务信息放入该队列中)
    3. 执行器有一个专门的回调线程定时批量从结果队列中取出任务结果,并且回调告知调度中心

xxl-job主要解决那些问题?

xxl-job主要用于解决分布式定时任务

类似于xxl-job的有哪些框架?xxl-job有哪些优势?

分布式定时任务指的是运行在分布式集群环境下的调度任务,同一份定时任务部署多份,则同一时刻应当只允许一个定时任务执行。

分布式定时任务调度的框架:quartz、elastic-job、xxl-job

功能quartzelastic-jobxxl-job
HA(高可用)多节点部署,通过数据库锁来保证只有一个节点执行任务通过zookeeper的注册和发现,可以动态添加服务器,支持水平扩容集群部署
任务分片不支持支持支持
文档完善完善完善完善
管理界面没有
难易程度简单较复杂简单
公司OpenSymphony当当网个人
缺点没有管理界面不支持任务分片,不适用于分布式场景需要引入zookeeper,增加系统复杂度,比较复杂通过获取数据库锁的方式,保证集群中执行任务的唯一性,性能不好
  • quartz和xxl-job对比:

    1. quartz采用api的方式调用任务,不方便,但是xxl-job使用的是管理界面。
    2. quartz比xxl-job代码侵入更强
    3. quartz调度逻辑和QuartzJobBean耦合在一个项目中,当任务增多,逻辑复杂的时候,性能会受到影响
    4. quartz底层以抢占式获取db锁并且由抢占成功的节点运行,导致节点负载悬殊非常大;xxl-job通过执行器实现协同分配式运行任务,各个节点比较均衡。
  • elastic-job和xxl-job对比:

    elastic-job是无中心化的,通过zookeeper的选举机制选出主服务器,如果主服务器挂了,重新选举出主服务器,因此elastic-job的扩展性和可用性较好,但是使用有一定的复杂度。使用于业务复杂,业务量大,服务器多。

    xxl-job是中心式的调度平台调度执行器执行任务,使用的是DB锁来保证集群分布式调用的一致性,学习简单,操作容易,成本不高。

如何使用xxl-job?

  1. 准备阶段:

    源码仓库地址:https://github.com/xuxueli/xxl-job

    中央仓库地址:

    <!-- http://repo1.maven.org/maven2/com/xuxueli/xxl-job-core/ -->
    <dependency>
        <groupId>com.xuxueli</groupId>
        <artifactId>xxl-job-core</artifactId>
        <version>${最新稳定版本}</version>
    </dependency>
    

    环境:

    • Maven3+
    • Jdk1.8+
    • Mysql5.7+
  2. 快速入门

    1. 源码下载解压,用idea打开,结果如图:
      在这里插入图片描述

      文件介绍:

      1. doc :文档资料
      2. xxl-job-admin :调度中心,项目源码
      3. xxl-job-core :公共Jar依赖
      4. xxl-job-executor-samples :执行器,Sample示例项目(大家可以在该项目上进行开发,也可以将现有项目改造生成执行器项目)
    2. 初始化数据库,运行doc/db/tables_xxl_job.sql中的sql生成数据库和表,如图:

在这里插入图片描述

  数据库中表介绍:

  - 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:系统用户表;
  1. 调度中心配置及部署

    • 调度中心配置文件地址:/xxl-job/xxl-job-admin/src/main/resources/application.properties

      配置文件的配置及说明:

      ### 调度中心JDBC链接
      spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
      spring.datasource.username=root
      spring.datasource.password=root
      spring.datasource.driver-class-name=com.mysql.jdbc.Driver
      ### 报警邮箱
      spring.mail.host=smtp.qq.com
      spring.mail.port=25
      spring.mail.username=xxx@qq.com
      spring.mail.password=xxx
      spring.mail.properties.mail.smtp.auth=true
      spring.mail.properties.mail.smtp.starttls.enable=true
      spring.mail.properties.mail.smtp.starttls.required=true
      spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
      ### 调度中心通讯TOKEN [选填]:非空时启用;
      xxl.job.accessToken=
      ### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文;
      xxl.job.i18n=zh_CN
      ## 调度线程池最大线程配置【必填】
      xxl.job.triggerpool.fast.max=200
      xxl.job.triggerpool.slow.max=100
      ### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
      xxl.job.logretentiondays=30
      

    部署调度中心

在这里插入图片描述

调度中心访问地址:http://localhost:8080/xxl-job-admin ,默认登录账号 “admin/123456”, 登录后运行界面如下图所示。

在这里插入图片描述

调度中心部署总结:

调度中心部署简单方便,耦合性比较低,如果集群部署需要保证其数据库的配置是一样的(保证一致性)和机器时钟保持 一致。

  1. 执行器配置及部署

    • pom中jar包的引入:

       <dependency>
                  <groupId>com.xuxueli</groupId>
                  <artifactId>xxl-job-core</artifactId>
                  <version>2.4.0-SNAPSHOT</version>
              </dependency>
      
    • 执行器配置及说明

      ### 调度中心部署根地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
      xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
      ### 执行器通讯TOKEN [选填]:非空时启用;
      xxl.job.accessToken=
      ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
      xxl.job.executor.appname=xxl-job-demo
      ### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
      xxl.job.executor.address=
      ### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
      xxl.job.executor.ip=
      ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
      xxl.job.executor.port=9999
      ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
      xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
      ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
      xxl.job.executor.logretentiondays=30
      
    • 执行器中的XxlJobConfig将根据配置文件中配置生成XxlJobSpringExecutor:

      @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.setLogPath(logPath);
              xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
      
              return xxlJobSpringExecutor;
          }
      
    • Bean模式下新建任务:(bean模式:以jobHandler方式维护在执行器端;需要结合JobHandler属性匹配执行器中的任务)

      1. 类模式

        • 继承抽象类IJobHandler中的execute()方法,IJobHandler还有init()和destory()方法,如图:

        在这里插入图片描述

        继承后execute()放入需要执行的业务逻辑,通过XxlJobExecutor.registJobHandler(“JobHandler的名称”,IJobHandler的实例);如图:

        在这里插入图片描述

        • 在调度中心添加调度器实例:

        在这里插入图片描述

        • 在调度中心任务管理模块,添加Cron表达式,路由策略等等信息

        在这里插入图片描述

        • 启动调度中心admin模块和执行器模块,执行器打印结果,本人设置的实例为两个,路由策略为轮询,所以结果如图:

      在这里插入图片描述

       总结:类模式,每个任务对应一个java类
      
      1. 方式模式(需要在spring的容器中开发job)

        • 为Job方法添加注解 “@XxlJob(value=“自定义jobhandler名称”, init = “JobHandler初始化方法”, destroy = “JobHandler销毁方法”)”,注解value值对应的是调度中心新建任务的JobHandler属性的值。如图:

          在这里插入图片描述

        • 在调度中心添加执行器实例

        • 在调度中心任务管理中添加调度任务

      在这里插入图片描述

      • 启动调度中心和执行器模块

        方法模式一个方式表示一个任务。

      执行器部署总结:

      ​ 执行器回调地址保持一致xxl.job.admin.addresses,执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;

      ​ 同一个执行器集群中xxl.job.executor.appname需要保持一致,配置中心根据该配置发现不同集群在线执行器实例的列表。

      附加调度中心新增任务是的路由策略和任务超时时间和失败重试次数:

      路由策略:当执行器集群部署时,提供丰富的路由策略,包括;
              FIRST(第一个):固定选择第一个机器;
              LAST(最后一个):固定选择最后一个机器;
              ROUND(轮询):;
              RANDOM(随机):随机选择在线的机器;
              CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
              LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举;
              LEAST_RECENTLY_USED(最近最久未使用):最久未使用的机器优先被选举;
              FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度;
              BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度;
              SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时系统自动传递分片参数;可根据分片			参数开发分片任务;
      任务超时时间:支持自定义任务超时时间,任务运行超时将会主动中断任务;
      失败重试次数;支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;
      

xxl-job的总结

​ xxl-job是一个中心式分布式的调度平台,调度中心和执行器解耦,执行器和业务代码耦合,代码的侵入性少,学习简单、开发简单、轻量级。

xxl-job的官方文档https://www.xuxueli.com/xxl-job

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/621489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot+vue 实现监控视频rtsp播放(java+Nginx+ffmpeg+flv.js)

其实原理就是: 将监控通过FFMPEG,推送给Nginx,前端通过Nginx地址拉取视频&#xff0c;就可以播放了。 1:安装FFMPEG. 2:下载并且配置nginx. 3:使用java代码实现调用cmd或者linux窗口,并且运行操作FFMPEG的命令&#xff0c;进行监控视频rtsp格式的推送&#xff0c;推送给nginx. …

模板方法设计模式的学习和使用

1、模板方法设计模式的学习 当涉及到一系列具有相似行为的算法或操作时,模板方法设计模式是一种有效的设计模式。它允许你定义一个算法的骨架,同时将某些步骤的实现细节交给子类来实现。   模板方法模式基于以下两个核心原则&#xff1a; 抽象类定义模板方法骨架&#xff1a…

chatgpt赋能python:Python将一张图片分割成多张:从理论到实践

Python将一张图片分割成多张&#xff1a;从理论到实践 简介 随着Internet的爆炸式增长&#xff0c;图片已经成为了我们生活中不可或缺的一部分。具有高质量、高清晰度的图片可以提升网站的美观程度&#xff0c;帮助网站吸引更多的用户。但是&#xff0c;有时候大型的图片并不…

chatgpt赋能python:Python并不是一门简单的编程语言

Python 并不是一门简单的编程语言 Python 是一门直观且易学的编程语言&#xff0c;这一点没有错&#xff0c;但是要说它是简单的&#xff0c;那其实是不准确的。Python 有着广泛的应用领域&#xff0c;包括人工智能、大数据分析、Web开发、自动化测试等。尽管初学者可以迅速上…

MySQL中BETWEEN AND(范围查询)

0 写在前面 MySQL 提供了 BETWEEN AND 关键字&#xff0c;用来判断字段的数值是否在指定范围内。 BETWEEN AND 需要两个参数&#xff0c;即范围的起始值和终止值。如果字段值在指定的范围内&#xff0c;则这些记录被返回。如果不在指定范围内&#xff0c;则不会被返回。 最近…

JS 装饰器

JS 装饰器 JavaScript 装饰器是一种以 符号开头的特殊语法&#xff0c;放在目标代码的前面用于包装或扩展代码功能。JavaScript 的装饰器语法目前仍处于提案阶段&#xff0c;现阶段使用的话需要通过 bable 等方式进行编译之后&#xff0c;才能在浏览器正常运行。装饰器分为两…

chatgpt赋能python:Python将空值替换成0

Python 将空值替换成 0 在数据分析和处理过程中&#xff0c;清洗数据往往是非常重要的一个环节。而在清洗数据过程中&#xff0c;经常会遇到空值&#xff08;Missing Values&#xff09;的问题。空值是指在数据集中出现的缺失值&#xff0c;它可能是由于数据输入错误、数据采集…

chatgpt赋能python:Python定义数据框:介绍和基础操作

Python定义数据框&#xff1a;介绍和基础操作 数据框是一种非常方便的数据结构&#xff0c;用于在Python中存储和处理表格数据。数据框可以看作是围绕Series对象构建的2D数据结构&#xff0c;Series是一种存储单个列的一维标记数组。在本文中&#xff0c;我们将介绍如何使用Py…

基于树莓派4B的车牌号识别

目录 0. 前言1. Raspbian系统烧录2. 更换清华源1. 查看树莓派系统版本2. 更换清华国内源3. Raspi镜像修改4. 系统源更新5. 错误排查 3. opencv安装4. 安装 hyperlprpip安装编译安装 5. 验证项目可行性 0. 前言 基于树莓派4B的车牌号识别系统 操作系统&#xff1a;Raspbian PC…

QT实例2(QTableWidget表格中增删数据)

案例介绍 本案例仅简单介绍QTableWidget部分使用方法&#xff0c;如在表格中插入或删除一行数据以及清空表格数据等。在添加数据时&#xff0c;设置了条件判断如正则表达式&#xff0c;若用户输入的数据不合法&#xff0c;则添加失败并提示用户错误的地方&#xff0c;便于用户…

IPsec的NAT穿越详解

问题场景 左边的支部&#xff0c;它的防火墙上联路由器&#xff0c;由于防火墙内部的接口使用的是私网地址&#xff0c;这就导致其无无法在公网上与对端防火墙进行IPsec的隧道建立 。所以必须在AR5上面不是NAT地址转换&#xff0c;由于一般使用的是NAPT&#xff0c;isakmp协议因…

ChatGPT评测

总结&#xff1a;ChatGPT很强大&#xff0c;用作学术方面的问答或者软件行业的辅助工具是有一定的作用&#xff0c;但是有些回答设置了限制&#xff0c;并且中文回答方面总是回答一半&#xff0c;需要一直让他继续说&#xff0c;篇幅不是很长&#xff0c;但是往往能说道精髓&am…

最新加装ChatGPT的New Bing申请流程(含出错解决办法)

两天获得New Bing测试资格流程记录 前言一、Microsoft Edge Dev浏览器下载二、Microsoft账号注册与登陆三、浏览器插件下载与添加四、加入候补名单五、写封信给Bing团队 前言 2023.03.08&#xff0c;下午收到了Microsoft Bing公司的邮件&#xff0c;提示测试资格申请成功&…

Qt Xlsx的基本使用

前言 在很多时候 &#xff0c;我们需要将数据导出&#xff0c;之前我是将数据表导出为CSV格式&#xff0c;CSV文件虽然可以用Excel打开&#xff0c;但相对于真正的Xlsx文件&#xff0c;还是有许多不足的。偶然之间&#xff0c;发现了QtXlsx这个第三方库。 1、QtXlsx官网对QtX…

makefile工具的使用,编写一个或多个文件!(简单易上手)

一、make 和 makefile 是什么 1. make 是一个 命令。 2. makefile 是一个 文件&#xff0c;可以自动化的构建项目。 3. 编写 makefile 需要&#xff1a; &#xff08;1&#xff09;依赖关系 &#xff08;2&#xff09;依赖方法 二、什么是依赖关系、什么是依赖方法 下面我简单…

【Java】Java核心要点总结:60

文章目录 1. 乐观锁一定就是好的吗2. Synchronized和ReentrantLock有什么异同3. ReentrantLock是如何实现可重入性的4. 和Synchronized相比&#xff0c;可以重入锁ReentrantLock实现原理有什么不同5. AQS框架 1. 乐观锁一定就是好的吗 乐观锁并不一定好&#xff0c;它有自己的适…

chatgpt赋能python:Python实现将一张图片贴到另一张图片上

Python实现将一张图片贴到另一张图片上 在图像处理中&#xff0c;往往需要将多张图片合成一张图片。这里介绍使用Python实现将一张图片贴到另一张图片上的方法。 准备工作 在实现之前&#xff0c;我们需要安装Python的图像处理库Pillow和numpy。 可以通过pip进行安装&#…

创建一个SpringBoot项目

Spring的诞生是为了简化JAVA程序的开发的 快速开发Spring而诞生的 SpringBoot为了快速开发Spring而诞生的一个框架 1)什么是SpringBoot&#xff1f;为什么要学它?(重要) Spring是包含了众多工具方法的IOC容器 SpringBoot就是Spring框架的脚手架&#xff0c;它的存在就是为了快…

软考A计划-系统架构师-官方考试指定教程-(2/15)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

chatgpt赋能python:Python屏幕输入介绍:了解命令行输入的基本知识

Python屏幕输入介绍&#xff1a;了解命令行输入的基本知识 Python是一种使用广泛的编程语言&#xff0c;用于编写各种类型的应用程序&#xff0c;包括图形用户界面应用程序和基于命令行的应用程序。对于基于命令行的应用程序来说&#xff0c;屏幕输入非常重要。本文将介绍Pyth…