XXL_JOB分布式任务调度平台

比眉伴天荒 2023-02-14 10:47 29阅读 0赞

前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

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

1、下载部署

1.1、下载

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

1.2、部署

1.2.1、目录结构:

  1. xxl-job-admin:调度中心
  2. xxl-job-core:公共依赖
  3. xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
  4. xxl-job-executor-sample-springbootSpringboot版本,通过Springboot管理执行器,推荐这种方式;
  5. xxl-job-executor-sample-springSpring版本,通过Spring容器管理执行器,比较通用;
  6. xxl-job-executor-sample-frameless:无框架版本;
  7. xxl-job-executor-sample-jfinalJFinal版本,通过JFinal管理执行器;
  8. xxl-job-executor-sample-nutzNutz版本,通过Nutz管理执行器;
  9. xxl-job-executor-sample-jbootjboot版本,通过jboot管理执行器;

1.2、SpringBoot选择

除了SpringBoot,其他的对我来说没有用,删掉其他的,我只保留的SpringBoot

image-20200514164259108

#

1.2.1、调度中心

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

1.2.1.1、properties

  1. ### web
  2. server.port=8080
  3. server.servlet.context-path=/xxl-job-admin
  4. ### actuator
  5. management.server.servlet.context-path=/actuator
  6. management.health.mail.enabled=false
  7. ### resources
  8. spring.mvc.servlet.load-on-startup=0
  9. spring.mvc.static-path-pattern=/static/**
  10. spring.resources.static-locations=classpath:/static/
  11. ### freemarker
  12. spring.freemarker.templateLoaderPath=classpath:/templates/
  13. spring.freemarker.suffix=.ftl
  14. spring.freemarker.charset=UTF-8
  15. spring.freemarker.request-context-attribute=request
  16. spring.freemarker.settings.number_format=0.##########
  17. ### mybatis
  18. mybatis.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
  19. #mybatis.type-aliases-package=com.xxl.job.admin.core.model
  20. ### datasource-pool
  21. spring.datasource.type=com.zaxxer.hikari.HikariDataSource
  22. spring.datasource.hikari.minimum-idle=10
  23. spring.datasource.hikari.maximum-pool-size=30
  24. spring.datasource.hikari.auto-commit=true
  25. spring.datasource.hikari.idle-timeout=30000
  26. spring.datasource.hikari.pool-name=HikariCP
  27. spring.datasource.hikari.max-lifetime=900000
  28. spring.datasource.hikari.connection-timeout=10000
  29. spring.datasource.hikari.connection-test-query=SELECT 1
  30. ### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致
  31. spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
  32. spring.datasource.username=root
  33. spring.datasource.password=123456
  34. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  35. ### 报警邮箱
  36. spring.mail.host=smtp.163.com
  37. spring.mail.port=25
  38. spring.mail.username=test_healerjean@163.com
  39. spring.mail.password=Zhangyj..123
  40. spring.mail.properties.mail.smtp.auth=true
  41. spring.mail.properties.mail.smtp.starttls.enable=true
  42. spring.mail.properties.mail.smtp.starttls.required=true
  43. spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
  44. ### 调度中心通讯TOKEN [选填]:非空时启用;
  45. xxl.job.accessToken=
  46. ### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文;
  47. xxl.job.i18n=zh_CN
  48. ## 调度线程池最大线程配置【必填】
  49. xxl.job.triggerpool.fast.max=200
  50. xxl.job.triggerpool.slow.max=100
  51. ### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
  52. xxl.job.logretentiondays=30

1.2.2:执行器项目

作用:负责接收“调度中心”的调度并执行;可直接部署执行器,也可以将执行器集成到现有业务项目中。

12.2.1、properties

  1. # web port
  2. server.port=8081
  3. # no web
  4. #spring.main.web-environment=false
  5. # log config
  6. logging.config=classpath:logback.xml
  7. ### 调度中心部署跟地址 [选填]:
  8. # 如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
  9. xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
  10. ### 执行器通讯TOKEN [选填]:非空时启用;XxlJobConfig
  11. xxl.job.accessToken=
  12. ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
  13. xxl.job.executor.appname=xxl-job-executor-sample
  14. ### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
  15. xxl.job.executor.address=
  16. ### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
  17. xxl.job.executor.ip=
  18. ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
  19. # 这里相当的重要,和上面应用的端口不同,也就是执行器通过下面的端口进行服务
  20. xxl.job.executor.port=9999
  21. ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
  22. xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
  23. ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
  24. xxl.job.executor.logretentiondays=30

1.3、启动:

1.3.1、启动调度中心:xxl-job-admin

  1. http://127.0.0.1:8080//xxl-job-admin
  2. admin/123456

image-20200514165313578

2、定时器介绍

2.1、配置属性

image-20200514175519193

2.1.1、执行器

任务的绑定的执行器,任务触发调度时将会自动发现注册成功的执行器, 实现任务自动发现功能; 另一方面也可以方便的进行任务分组。每个任务必须绑定一个执行器, 可在 “执行器管理” 进行设置;

image-20200514175450889

2.1.2、 任务描述

任务的描述信息,便于任务管理;

image-20200514175618084

2.1.3、路由策略

当执行器集群部署时,提供丰富的路由策略,包括;


















































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

2.1.4、Cron

触发任务执行的Cron表达式;

2.1.5、运行模式










































BEAN模式 任务以JobHandler方式维护在执行器端;需要结合 “JobHandler” 属性匹配执行器中任务;
GLUE模式 任务以源码方式维护在调度中心;任务以JobHandler方式维护在执行器端;需要结合 “JobHandler” 属性匹配执行器中任务;
GLUE模式(Java) 该模式的任务实际上是一段继承自IJobHandler的Java类代码并 “groovy” 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;
GLUE模式(Shell) 该模式的任务实际上是一段 “shell” 脚本;
GLUE模式(Python) 该模式的任务实际上是一段 “python” 脚本;
GLUE模式(PHP) 该模式的任务实际上是一段 “php” 脚本;
GLUE模式(NodeJS) 该模式的任务实际上是一段 “nodejs” 脚本;
GLUE模式(PowerShell) 该模式的任务实际上是一段 “PowerShell” 脚本;

2.1.6、JobHandler

运行模式为 “BEAN模式” 时生效,对应执行器中新开发的JobHandler类“@JobHandler”注解自定义的value值;

2.1.7、阻塞处理策略

调度过于密集执行器来不及处理时的处理策略;

如果当前任务还没执行完成,又来了任务的处理策略 。我们一定要尽可能避免此类情况






















阻塞处理策略
单机串行(默认) 调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
丢弃后续调度 调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
覆盖之前调度 调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;

2.1.9、子任务Id

每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。

2.1.10、任务超时时间

支持自定义任务超时时间,任务运行超时将会主动中断任务,同下面调度日志里面的终止任务;

2.1.11、失败重试次数

支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;

2.1.12、负责人

任务的负责人;

2.1.13、报警邮件

任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔;

2.1.14、执行参数

任务执行所需的参数

3、BEAN模式

任务以JobHandler方式维护在执行器端;需要结合 “JobHandler” 属性匹配执行器中任务

3.1、方法形式

3.1.1、执行器项目

  1. package com.xxl.job.executor.service.jobhandler.bean;
  2. import com.xxl.job.core.biz.model.ReturnT;
  3. import com.xxl.job.core.handler.annotation.XxlJob;
  4. import com.xxl.job.core.log.XxlJobLogger;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import org.springframework.stereotype.Component;
  9. /** * XxlJob开发示例(Bean模式) * <p> * 开发步骤: * 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)" * 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。 * 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志; */
  10. @Component
  11. @Slf4j
  12. public class BeanMethodXxlJob {
  13. /** * 1、简单任务示例(Bean模式) */
  14. @XxlJob("demoJobHandler")
  15. public ReturnT<String> demoJobHandler(String param) throws Exception {
  16. log.info("任务【demoJobHandler】开始执行, 请求参数:{}", param);
  17. //任务调度器日志
  18. XxlJobLogger.log("XXL-JOB, 请求参数:{}", param);
  19. return ReturnT.SUCCESS;
  20. }
  21. /** * 2、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑; */
  22. @XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
  23. public ReturnT<String> demoJobHandler2(String param) throws Exception {
  24. log.info("任务【demoJobHandler2】开始执行, 请求参数:{}", param);
  25. //任务调度器日志
  26. XxlJobLogger.log("XXL-JOB, Hello World.");
  27. return ReturnT.SUCCESS;
  28. }
  29. public void init() {
  30. log.info("任务【demoJobHandler2】开始执行 init");
  31. }
  32. public void destroy() {
  33. log.info("任务【demoJobHandler2】开始执行 destroy");
  34. }
  35. }

3.1.2、调度中心页面操作

3.1.2.1、demoJobHandler

  1. 0 */1 * * * ? 每分钟执行一次

image-20200514171037105

image-20200514171544980

3.1.2.2、demoJobHandler2

image-20200514171746883

image-20200514171759076

4、GLUE(java)模式

任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并 “groovy” 源码方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;

4.1、GLUE模式(Java)

4.1.1、glueJobHandle

4.1.1.1、创建

image-20200514173917522

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jp2MWFgF-1591086758306)(https://raw.githubusercontent.com/HealerJean/HealerJean.github.io/master/blogImages/image-20200514173938394.png)\]

  1. package com.xxl.job.service.handler;
  2. import com.xxl.job.core.log.XxlJobLogger;
  3. import com.xxl.job.core.biz.model.ReturnT;
  4. import com.xxl.job.core.handler.IJobHandler;
  5. public class DemoGlueJobHandler extends IJobHandler {
  6. @Override
  7. public ReturnT<String> execute(String param) throws Exception {
  8. XxlJobLogger.log("GlueJob 请求参数:{}", param);
  9. return ReturnT.SUCCESS;
  10. }
  11. }

image-20200514174042724

4.1.1.2、查看日志

image-20200514174259824

image-20200514174320434

  1. 2020-05-14 17:41:57 [com.xxl.job.core.thread.JobThread#run]-[124]-[Thread-19]
  2. ----------- xxl-job job execute start -----------
  3. ----------- Param:HealerJean
  4. 2020-05-14 17:41:57 [com.xxl.job.core.handler.impl.GlueJobHandler#execute]-[26]-[Thread-19] ----------- glue.version:1589449244000 -----------
  5. 2020-05-14 17:41:57 [sun.reflect.NativeMethodAccessorImpl#invoke0]-[-2]-[Thread-19] GlueJob 请求参数:HealerJean
  6. 2020-05-14 17:41:57 [com.xxl.job.core.thread.JobThread#run]-[164]-[Thread-19]
  7. ----------- xxl-job job execute end(finish) -----------
  8. ----------- ReturnT:ReturnT [code=200, msg=null, content=null]
  9. 2020-05-14 17:41:57 [com.xxl.job.core.thread.TriggerCallbackThread#callbackLog]-[191]-[xxl-job, executor TriggerCallbackThread]
  10. ----------- xxl-job job callback finish.
  11. [Load Log Finish]

5、操作指南

5.1、执行器管理

AppName: 是每个执行器集群的唯一标示AppName, 执行器会周期性以AppName为对象进行自动注册。可通过该配置自动发现注册成功的执行器, 供任务调度时使用;

名称:执行器的名称, 因为AppName限制字母数字等组成,可读性不强, 名称为了提高执行器的可读性;

排序:执行器的排序, 系统中需要执行器的地方,如任务新增, 将会按照该排序读取可用的执行器列表;

注册方式:调度中心获取执行器地址的方式

1、自动注册:执行器自动进行执行器注册,调度中心通过底层注册表可以动态发现执行器机器地址

2、手动录入:人工手动录入执行器的地址信息,多地址逗号分隔,供调度中心使用;

机器地址:“注册方式”为”手动录入”时有效,支持人工维护执行器的地址信息;`

image-20200514184425782

5.2、调度日志

image-20200514184833583

调度时间:”调度中心”触发本次调度并向”执行器”发送任务执行信号的时间;

调度结果:”调度中心”触发本次调度的结果,200表示成功,500或其他表示失败;

调度备注:”调度中心”触发本次调度的日志信息;

  1. 任务触发类型:失败重试触发
  2. 调度机器:10.236.150.223
  3. 执行器-注册方式:自动注册
  4. 执行器-地址列表:[http://10.236.150.223:9999/]
  5. 路由策略:第一个
  6. 阻塞处理策略:单机串行
  7. 任务超时时间:0
  8. 失败重试次数:3
  9. >>>>>>>>>>>触发调度<<<<<<<<<<<
  10. 触发调度:
  11. addresshttp://10.236.150.223:9999/
  12. code200
  13. msgnull

执行时间:”执行器”中本次任务执行结束后回调的时间;

执行结果:”执行器”中本次任务执行的结果,200表示成功,500或其他表示失败;

执行备注:”执行器”中本次任务执行的日志信息

操作:

1、”执行日志”按钮:点击可查看本地任务执行的详细日志信息;详见“4.8 查看执行日志”;

image-20200514185319106

2、”终止任务”按钮:仅针对执行中的任务。在任务日志界面,点击右侧的“终止任务”按钮,将会向本次任务对应的执行器发送任务终止请求,将会终止掉本次任务,同时会清空掉整个任务执行队列。

任务终止时通过 “interrupt” 执行线程的方式实现, 将会触发 “InterruptedException” 异常。因此如果JobHandler内部catch到了该异常并消化掉的话, 任务终止功能将不可用。

因此, 如果遇到上述任务终止不可用的情况, 需要在JobHandler中应该针对 “InterruptedException” 异常进行特殊处理 (向上抛出) , 正确逻辑如下:

  1. try{
  2. // do something
  3. } catch (Exception e) {
  4. if (e instanceof InterruptedException) {
  5. throw e;
  6. }
  7. logger.warn("{}", e);
  8. }

而且,在JobHandler中开启子线程时,子线程也不可catch处理”InterruptedException”,应该主动向上抛出。

任务终止时会执行对应JobHandler的”destroy()”方法,可以借助该方法处理一些资源回收的逻辑。

5.3、用户管理

管理员:拥有全量权限,支持在线管理用户信息,为用户分配权限,权限分配粒度为执行器;

普通用户:仅拥有被分配权限的执行器,及相关任务的操作权限;

image-20200514185612864

6、总体设计

6.1、源码目录介绍

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

6.2、调度数据库

  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:系统用户表;

7、quartz的不足

问题一:调用API的的方式操作任务,不人性化;

问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。

问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务;

问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务(其实也是乐观锁获取任务),充分发挥集群优势,负载各节点均衡。

主要还是入侵比较严重吧。而且分布式用XXLJob,更好,可以给多个分布式系统节点提供服务

ContactAuthor

发表评论

表情:
评论列表 (有 0 条评论,29人围观)

还没有评论,来说两句吧...

相关阅读