分布式定时任务xxl-Job

news/2024/5/18 23:57:30/文章来源:https://blog.csdn.net/qq_24426227/article/details/131633888

目录

前言

项目介绍

1.源码目录介绍

2 “调度数据库”配置

3 架构设计

3.1 设计思想

5.3.3 架构图

实战

1.服务端部署

2.执行端配置

3.任务开发

3.1 基于方法注解任务

3.2 基于api任务

3.3 分片广播任务

4.任务执行

4.1 单任务执行

4.2 子任务执行

4.3 分片广播任务执行

5.任务日志

总结

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


前言

   任务调度是java项目中常用的一种组件,可以指定任务在何时进行触发,最熟悉的是spring框架里面的quartz,较流行的有一些分布式调度组件,比如elastic-job/azkaban,都是基于quartz二次开发的,今天介绍一款分布式的任务调度器xxl-job。

项目介绍

  xxl-job是一款极容易学习上手的轻量级开源分布式调度框架,分为管理端和执行端两块,管理端负责配置任务信息以及查看任务执行日志,执行端只需要配置与管理端的连接信息就可以进行具体的任务逻辑开发了,目前版本还在持续迭代中,使用简单,功能强大,具体功能特性可以看下官方介绍。废话不多说,直接进入实战把。

官网地址: 分布式任务调度平台XXL-JOB

1.源码目录介绍

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

2 “调度数据库”配置

XXL-JOB调度模块基于自研调度组件并支持集群部署,调度数据库表说明如下:

  1. - xxl_job_lock:任务调度锁表;
  2. - xxl_job_group:执行器信息表,维护任务执行器信息;
  3. - xxl_job_info:调度扩展信息表: 用于保存XXL-JOB调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等;
  4. - xxl_job_log:调度日志表: 用于保存XXL-JOB任务调度的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等;
  5. - xxl_job_log_report:调度日志报表:用户存储XXL-JOB任务调度日志的报表,调度中心报表功能页面会用到;
  6. - xxl_job_logglue:任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能;
  7. - xxl_job_registry:执行器注册表,维护在线的执行器和调度中心机器地址信息;
  8. - xxl_job_user:系统用户表;

3 架构设计

3.1 设计思想

将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。

因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性

3.2 系统组成

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

5.3.3 架构图

实战

1.服务端部署

从https://github.com/xuxueli/xxl-job下载项目,用mysql客户端工具Navicat执行项目根目录下doc/db/table_xxl_job.sql文件,库名自己可以自行修改,一共8张表,如下:

1.创建一个新的spring boot项目,将下载的xxl-job-admin目录下的文件以及pom.xml文件都拷贝到新建的项目中(如果不想新建项目可以直接用下载下来的项目进行修改部署),修改application.properties中的数据库连接信息。

2.小编是自己创建的新项目,需要手动改了pom.xml依赖xxl-job-core的版本为2.2.0

3.修改logback.xml中的日志输出路径。

好了,以上3步曲就搞定整个服务端配置了,启动项目,并访问http://localhost:8080/xxl-job-admin/ ,默认管理员账号admin/123456进行登录。 这交互,可以啊,是不是很带感。

2.执行端配置

创建一个新的module,跟服务端一样,也需要修改下logback.xml以及在pom.xml添加xxl-job-core的依赖。

为了模拟分布式效果,小编创建了2个配置文件来区分2个执行服务。

application-9998.properties

# web port
server.port=8081
# no web
#spring.main.web-environment=false
# log config
logging.config=classpath:logback.xml### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin### xxl-job, access token
xxl.job.accessToken=### xxl-job executor appname
xxl.job.executor.appname=my-job-executor
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=
xxl.job.executor.port=9998
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

application-9999.properties

# web port
server.port=8082
# no web
#spring.main.web-environment=false# log config
logging.config=classpath:logback.xml### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### xxl-job, access token
xxl.job.accessToken=### xxl-job executor appname
xxl.job.executor.appname=my-job-executor
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=
xxl.job.executor.port=9999
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

细心的童鞋会发现只有server.port和xxl.job.executor.port不同,执行器服务跟spring boot一样,自带内嵌tomcat,也会暴露一个端口注册到服务端,进行高可用负载。

创建一个java config类,定义一个使用配置的XxlJobSpringExecutor执行类,如下

@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.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;@Beanpublic 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;}

配置2个启动配置,分别启动,效果如下:

完美启动2个服务,看下服务端平台是不是有这两台执行服务的注册信息。

注意:为了演示,事先创建了一个执行器,AppName一定要与配置文件中xxl.job.executor.appname一致。

3.任务开发

3.1 基于方法注解任务

话不多说,直接上代码把,毕竟代码是程序员最好的交流方式。

/*** 1、注解任务*/@XxlJob(value = "myJobAnnotationHandler",init = "init", destroy = "destroy")public ReturnT<String> myJobAnnotationHandler(String param) throws Exception {XxlJobLogger.log("XXL-JOB-ANNOTATION, myJobAnnotationHandler.");log.info("my first annotation job run, param: {},port:{}",param,port);return ReturnT.SUCCESS;}public void init(){log.info("my annotation job  init");}public void destroy(){log.info("my job annotation job destory");}

3.2 基于api任务

@Slf4j
public class ApiJob extends IJobHandler {@Overridepublic ReturnT<String> execute(String param) throws Exception {XxlJobLogger.log("XXL-JOB-API, Hello World.");log.info("my job api run, param: {}",param);return ReturnT.SUCCESS;}
}
@PostConstructpublic void registerHandler(){XxlJobExecutor.registJobHandler("myJobApiHandler",new ApiJob());}

3.3 分片广播任务

/*** 2、分片任务*/@XxlJob("myShardJobAnnotationHandler")public ReturnT<String> myShardJobAnnotationHandler(String param) throws Exception {XxlJobLogger.log("XXL-JOB-ANNOTATION, myShardJobAnnotationHandler.");log.info("my shard job run, param: {}",param);ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();log.info("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());// 业务逻辑for (int i = 0; i < shardingVO.getTotal(); i++) {if (i == shardingVO.getIndex()) {log.info("第 {} 片, 命中分片开始处理", i);} else {log.info("第 {} 片, 忽略", i);}}return ReturnT.SUCCESS;}

上面是整理的比较实用的任务创建方式,个人偏好于注解形式,方法上加一个注解就完事了。

4.任务执行

剩下的就是傻白甜的界面操作了,走起。

4.1 单任务执行

创建一个路由策略为轮询的任务,指定corn表达式,并填入JobHandler为myJobAnnotationHandler,myJobAnnotationHandler其实就是spring IOC容器中管理bean的名称,有兴趣的童鞋可以看下源码。

为了演示效果,点击执行一次并进行任务参数输入。

轮询调用执行器服务效果如下:

4.2 子任务执行

更新任务,并指定子任务id为5,多个子任务的需要以逗号隔开

执行任务结果如下

4.3 分片广播任务执行

分片任务其实就是广播功能,每次触发,每个执行服务的业务执行类都会被调用,类似于kafka里面的不同消费组都要对同一个topic进行消费一样。

执行后的效果如下

太强势了,需要定时刷新项目中的配置信息,用这个方式很完美。

5.任务日志

任务日志其实是很重要的一块,方便回溯任务历史执行情况, 以便跟踪问题并矫正丢失的业务数据

查看调度备注,父子任务调度信息非常详细,子任务可以通过执行备注查看执行情况

查看控制台输出,里面的日志是执行器中XxlJobLogger类打印出来的

总结

      xxl-job还有很多特性,个人觉得实用的有任务超时控制/任务失败重试/任务失败告警 /邮件报警,这些都是与业务紧密相关的功能,能有效的规避生产事故而达到止损目的。

    对比下之前使用过的任务调度组件,xxl-job将任务调度和执行进行解耦,大大提高了可用性和扩展性,代码的侵入性几乎没有,与spring boot无配置化,开箱即用的理念非常契合,任务调度平台可视化操作的确是爽爆了,感觉小白都可以用。

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

功能

quartz

elastic-job

xxl-job

HA(高可用)

多节点部署,通过数据库锁来保证只有一个节点执行任务

通过zookeeper的注册和发现,可以动态添加服务器,支持水平扩容

集群部署

任务分片

不支持

支持

支持

文档完善

完善

完善

完善

管理界面

没有

难易程度

简单

较复杂

简单

公司

OpenSymphony

当当网

个人

缺点

没有管理界面不支持任务分片,不适用于分布式场景

需要引入zookeeper,增加系统复杂度,比较复杂

通过获取数据库锁的方式,保证集群中执行任务的唯一性,性能不好

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一、rocketmq整体架构及nameServer源码分析

RocketMQ源码深入剖析 1 RocketMQ介绍 RocketMQ 是阿里巴巴集团基于高可用分布式集群技术&#xff0c;自主研发的云正式商用的专业消息中间件&#xff0c;既可为分布式应用系统提供异步解耦和削峰填谷的能力&#xff0c;同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠…

一次零基础靶机渗透细节全程记录

一、打靶总流程 1.确定目标&#xff1a; 在本靶场中&#xff0c;确定目标就是使用nmap进行ip扫描&#xff0c;确定ip即为目标&#xff0c;只是针对此靶场而言。其他实战中确定目标的方式包括nmap进行扫描&#xff0c;但不局限于这个nmap。 2.信息收集&#xff1a; 比如平常挖…

经典的网络安全技术

以我的理解&#xff0c;“黑客”大体上应该分为“正”、“邪”两类&#xff0c;正派黑客依靠自己掌握的知识帮助系统管理员找出系统中的漏洞并加以完善&#xff0c;而邪派黑客则是通过各种黑客技能对系统进行攻击、入侵或者做其他一些有害于网络的事情&#xff0c;因为邪派黑客…

RPC分布式网络通信框架(二)—— moduo网络解析

文章目录 一、框架通信原理二、框架初始化框架初始化 三、调用端&#xff08;客户端&#xff09;调用端框架调用端主程序 四、提供端&#xff08;服务器&#xff09;提供端主程序提供端框架NotifyService方法Run方法muduo库的优点网络代码RpcProvider::OnConnection业务代码Rpc…

win11利用start11实现全屏菜单,磁贴配置

Win11磁贴配置 最近电脑还是升级到 win11 了。我之前采用的美化方案是桌面上的图标全部移到 win10 开始菜单里的全屏菜单上&#xff0c;用磁贴贴一排。每次要访问文件的时候都去开始菜单里找&#xff0c;而不是放在桌面上&#xff0c;这样桌面也可以空出来欣赏壁纸。参考配置链…

springboot+MySQL大学生体质测试管理系统

功能需求分析的任务是通过详细调查大学生体质测试的测试信息管理系统要处理的所有对象&#xff0c;通过充分了解大学生体质测试管理系统的工作流程&#xff0c;明确使用者的各种需求&#xff0c;充分思考之后可能扩充和改变的情况&#xff0c;然后在这个基础上来设计数据库。

论文笔记--TinyBERT: Distilling BERT for Natural Language Understanding

论文笔记--TinyBERT: Distilling BERT for Natural Language Understanding 1. 文章简介2. 文章概括3 文章重点技术3.1 Transformer Distillation3.2 两阶段蒸馏 4. 数值实验5. 文章亮点5. 原文传送门6. References 1. 文章简介 标题&#xff1a;TinyBERT: Distilling BERT fo…

赛效:如何用在线压缩GIF图片

1&#xff1a;在电脑网页上打开并登录快改图&#xff0c;点击左侧菜单栏里的“GIF压缩”。 2&#xff1a;点击页面中间的上传按钮&#xff0c;将电脑本地的GIF文件上传上去。 3&#xff1a;GIF文件上传成功后&#xff0c;设置下方压缩设置&#xff0c;点击右下角“开始压缩”。…

数据结构(王卓版)——线性表

数据的存储结构之线性表 1、线性表的定义和特点

java后端开发环境搭建 mac

在mac pro上搭建一套java 后端开发环境&#xff0c;主要安装的内容有&#xff1a;jdk、maven、git、tomcat、mysql、navicat、IntelliJ、redis。 本人mac pro的系统为mac OS Monterey 12.6.7&#xff0c;主机的硬件架构为x86_64。 左上角关于本机查看系统版本&#xff1b;终端…

前端框架Layui实现动态树效果(书籍管理系统左侧下拉列表)

目录 一、前言 1.什么是树形菜单 2.树形菜单的使用场景 二、案例实现 1.需求分析 2.前期准备工作 ①导入依赖 ②工具类 BaseDao&#xff08;通用增删改查&#xff09; BuildTree(完成平级数据到父子级的转换) ResponseUtil&#xff08;将数据转换成json格式进行回显&…

数据可视化之Tableau可视化||绘制标靶图

标靶图是一种用于评估、测试和优化计算机视觉算法的基准测试工具。它通常由多个具有不同特征的目标物体组成,如车辆、行人、交通信号灯等,同时包括各种不同的复杂场景,如城市街道、高速公路和人行道等。通过使用标靶图,研究人员可以检验算法的准确性、速度和适应性,同时拓…

由于找不到d3dx9_43.dll,有什么可靠的修复方法?

由于找不到d3dx9_43.dll&#xff0c;无法继续执行代码&#xff0c;这种情况大家是否有遇见过&#xff1f;其实就算没遇到过&#xff0c;大家应该也有遇到别的dll文件丢失吧&#xff1f;道理都一样&#xff0c;都是dll文件丢失&#xff0c;我们只需要把它给修复就可以了&#xf…

JVM的类加载机制和垃圾回收机制

目录 类加载机制类加载机制的步骤加载验证准备解析初始化 双亲委派模型工作原理双亲委派模型的优点 垃圾回收机制死亡对象的判断可达性分析算法可达性分析算法的缺点引用计数算法循环引用问题 垃圾回收算法标记-清除算法复制算法标记-整理算法分代算法 类加载机制 对于任意一个…

Antd List组件增加gutter属性后出现横向滚动,如何解决

第一次使用ant design的List列表组件&#xff0c;设置gutter间隔属性后&#xff0c;页面出现了横向滚动条&#xff0c;查阅文档发现是由于加间隔后导致容器宽度被撑开&#xff0c;ant design官方默认给外层容器加了margin-left和margin-right 解决方法是在外层容器预留一定的pa…

【sql注入-堆叠注入】多语句执行、结合其他注入

目录 堆叠注入 一、语法介绍 二、漏洞示例 三、常见形式 网络安全O 堆叠注入 一、语法介绍&#xff1a; 版本&#xff1a; 可以影响几乎所有的关系型数据库 原理&#xff1a; 将多条语句堆叠在一起进行查询&#xff0c;且可以执行多条SQL语句 语句之间以分号(;)隔开&#…

图像分类——模型微调

目录 微调热狗识别获取数据集模型构建与训练 微调 热狗识别 获取数据集 import tensorflow as tf import pathlibtraindirhotdog/train testdirhotdog/test image_gentf.keras.preprocessing.image.ImageDataGenerator(rescale1/255) train_data_genimage_gen.flow_from_direc…

探索PlanetScale:划分分支的MySQL Serverless平台

最近我发现了一个非常有趣的国外MySQL Serverless平台&#xff0c;它叫做PlanetScale。这个平台不仅仅是一个数据库&#xff0c;它能像代码一样轻松地创建开发和测试环境。你可以从主库中拉出一个与之完全相同结构的development或staging数据库&#xff0c;并在这个环境中进行开…

Python模拟MQTT v3.1.1服务器

示例代码 import logging import asyncio from hbmqtt.broker import Broker# 设置日志级别为DEBUG logging.basicConfig(levellogging.DEBUG)# 创建MQTT服务器 broker Broker()# 启动MQTT服务器 async def start_broker():await broker.start()# 停止MQTT服务器 async def s…

Leangoo领歌敏捷管理工具标签升级,企业级标签组上线

在Leangoo领歌敏捷工具中&#xff0c;标签通常用作对任务的分类&#xff0c;或任务的优先级区分等。这次我们发布了大家期待已久的“企业级标签组”功能&#xff0c;标签可以统一管理啦&#xff5e; 之前&#xff0c;Leangoo领歌的标签功能只限于单个看板使用&#xff0c;需要…