当前位置:   article > 正文

分布式定时任务框架xxl-job入门与基础知识_案例 使用分布式调度框架该考虑哪些问题?

案例 使用分布式调度框架该考虑哪些问题?

分布式定时任务框架XXL-JOB

重点参考:

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

参考文章:芋道 Spring Boot 定时任务入门

定时任务背景

定时任务需求

几个非常常见的业务场景:

  1. 某系统凌晨要进行数据备份。
  2. 某电商平台,用户下单半个小时未支付的情况下需要自动取消订单。
  3. 某媒体聚合平台,每 10 分钟动态抓取某某网站的数据为自己所用。
  4. 某博客平台,支持定时发送文章。
  5. 某基金平台,每晚定时计算用户当日收益情况并推送给用户最新的数据。

这些场景往往都要求我们在某个特定的时间去做某个事情

Java传统定时任务方案–单机定时任务
  • java.util.Timer \ScheduledExecutorService (都无法使用 Cron 表达式指定任务执行的具体时间)
  • Spring Task\SpringBoot注解@Scheduled(Spring 自带的定时调度只支持单机,并且提供的功能比较单一)
  • 时间轮。时间轮是一个环形的队列(底层一般基于数组实现),队列中的每一个元素(时间格)都可以存放一个定时任务列表。
分布式任务调度问题

分布式集群的模式下,如果采用集中式的任务调度方式,会带来一些问题,比如

  1. 集群部署的定时任务如何保证调度(比如重复执行降低效率)?
  2. 如何动态地调整定时任务的执行时间? (不重启服务实现)
  3. 如何实现故障转移?
  4. 如何对定时任务进行监控?
  5. 业务量比较大,单机性能如何扩展?
分布式任务调度解决方案

由于集中式的定时任务调度需要解决一系列问题 ,所以在演进的过程中产生一些解决办法。

  1. 数据库唯一约束,避免定时任务重复执行;
  2. 使用配置文件、redis、 mysql作为调度的开关;
  3. 使用分布式锁实现调度的控制;
  4. 使用分布式任务调度平台(大公司自研或开源项目)TBSchedule、ScheduleX、Elastric-Job、Saturn、Google Cron、XXL-JOB 系统;

XXL-JOB架构

在这里插入图片描述

调度中心:服务端:是一个web管理后台

执行器:客户端:就是我们希望自动执行的代码,业务逻辑

自研的调度模块,通过RPC远程调用

调度和执行之间的解耦合
  • 将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。
  • 将任务抽象成分散的 JobHandler ,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的 JobHandler中 业务逻辑。

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

XXL-Job 是中心化的任务调度平台

从调度系统的角度来看,可以分成两类:

  • 中心化: 调度中心和执行器分离,调度中心统一调度,通知某个执行器处理任务。
  • 去中心化:调度中心和执行器一体化,自己调度自己执行处理任务。

XXL-JOB调度中心解析

在这里插入图片描述

任务管理和执行器管理的区分?

执行器管理是调度中心连接的多个执行器的名称、地址等进行管理。

任务管理是对xx执行器进行任务的具体设置,比如负责人、任务描述、超时时间、失败次数等等

任务管理设置详解 具体可参考官方文档
路由策略:

在执行器集群部署时,使用不同的路由策略,比如:

FIRST(第一个):固定选择第一个机器;

RANDOM(随机):随机选择在线的机器;

ROUND(轮询)等等

调度类型:
  1. 无:该类型不会主动触发调度
  2. CRON:该类型将会通过CRON,触发任务调度;
  3. 固定速度:该类型将会以固定速度,触发任务调度;按照固定的间隔时间,周期性触发;
  4. 固定延迟:该类型将会以固定延迟,触发任务调度;按照固定的延迟时间,从上次调度结束后开始计算延迟时间,到达延迟时间后触发下次调度;
Cron表达式:

Cron表达式是一个具有时间含义的字符串,字符串以56个空格隔开,分为67个域,格式为X X X X X X X。其中X是一个域的占位符。最后一个代表年份的域非必须,可省略。

具体设置方式参考:https://help.aliyun.com/document_detail/64769.html

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

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

阻塞处理策略

阻塞处理策略是调度过于密集执行器来不及处理时的处理策略。

  1. 单机串行(默认):调度请求进入单机执行器后,调度请求进入FIFO队列并以串行方式运行;
  2. 丢弃后续调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,本次请求将会被丢弃并标记为失败;
  3. 覆盖之前调度:调度请求进入单机执行器后,发现执行器存在运行的调度任务,将会终止运行中的调度任务并清空队列,然后运行本地调度任务;
还有任务描述、 负责人、报警邮件等等比较容易理解
调度中心其他模块

运行报表、调度日志、执行器管理都比较常规。

用户管理(权限管理)的功能比较弱,一般公司会进行二次开发。

调度中心集群部署

调度中心支持集群部署,提升调度系统容灾和可用性。支持Docker镜像搭建。

即实现多个调度中心,高可用,官方文档建议通过nginx为调度中心集群做负载均衡。

调度中心邮件警报

利用spring框架中集成的SMTP邮件服务

配置方法参考:

  • https://writing-bugs.blog.csdn.net/article/details/125440957

发件人是在调度中心application.properties中设置好,包括授权码

收件人在任务设置界面设置好

在这里插入图片描述

XXL-JOB执行器解析

执行器配置文件
//执行器连接调度中心的地址和token要设置好
xxl.job.admin.addresses=http://127.0.0.1:8002/xxl-job-admin
xxl.job.accessToken=default_token
//执行器名字、端口、ip等
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.address=
xxl.job.executor.ip=
xxl.job.executor.port=9999
//建议使用自动获取IP,多网卡时可手动设置指定IP
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
XxlJobConfig.class

里面有spring的bean

执行器真正的业务逻辑:SampleXxlJob.class

注意使用@Component注解@XxlJob注解。

还可以使用String param = XxlJobHelper.getJobParam()来获取参数(调度中心设置的参数)

注意这里之前注解是@JobHandler,现在都更新为@XxlJob,网上很多旧的教程还在用@JobHandler,官方文档教程也还没完全更新。

项目部署

XXL-JOB调度中心和执行器交互

  1. 进入调度中心

  2. 新增执行器(上述各种设置)

  3. 新增任务(上述各种设置)

执行器打包部署

执行器集群部署具体方法

  1. 调度中心-执行器管理-填写多个机器地址,逗号分隔

  2. 任务管理-设置路由策略,比如使用轮询的方式

  3. 测试

执行器集群部署时,官方要求:

  • 执行器回调地址(xxl.job.admin.addresses)需要保持一致;执行器根据该配置进行执行器自动注册等操作。
  • 同一个执行器集群内AppName(xxl.job.executor.appname)需要保持一致;调度中心根据该配置动态发现不同集群的在线执行器列表。

IDEA多实例运行

利用IDEA实现本地“模拟集群”,即把同一个项目(执行器、实例、服务)同时在多个端口号运行。

通过Run中的Edit Configurations=> Allow multiple instances,修改一下端口号等配置,再点击运行实现本地多实例运行。

DEMO测试

目标:将上述项目进行执行器集群部署、每隔两秒定时输出一行信息+调度中心传入的参数(paramtest)。

@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
        String param = XxlJobHelper.getJobParam();
        System.out.println("任务执行测试"+"参数:"+param+"time:"+new Date());
}
  • 1
  • 2
  • 3
  • 4
  • 5

执行器有两个同样的服务,模拟集群。
在这里插入图片描述

调度中心设置2秒执行一次,路由策略为轮询,两个服务轮流2s输出一次,正常

在这里插入图片描述

在这里插入图片描述

也进行了故障转移的测试。

与quartz进行对比

Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题:

  • 问题一:调用API的的方式操作任务,不人性化;
  • 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
  • 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务;
  • 问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。

rtz进行对比

Quartz作为开源作业调度中的佼佼者,是作业调度的首选。但是集群环境中Quartz采用API的方式对任务进行管理,从而可以避免上述问题,但是同样存在以下问题:

  • 问题一:调用API的的方式操作任务,不人性化;
  • 问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
  • 问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况下,此时调度系统的性能将大大受限于业务;
  • 问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。

XXL-JOB弥补了quartz的上述不足之处

附录:基础知识

这包含了学习过程中遇到的相关技术和知识,包括没接触过的和之前学过但需要再重点复习的。

集群、分布式、SOA和微服务。
集群:

同一个业务,部署在多个服务器上。代表技术:Nginx集群

分布式:

一个业务分拆成多个子业务,部署在不同的服务器上。

分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。

好的设计应该是分布式和集群的结合,先分布式再集群,具体实现就是业务拆分成很多子业务,然后针对每个子业务进行集群部署,这样每个子业务如果出了问题,整个系统完全不会受影响。

SOA:

面向服务架构。中间有ESB:企业服务总线。目的是将原先系统间散乱、无规划的网状结构,梳理成规整、可治理的星形结构。

为了解决分布式中出现的复杂的子业务直接的调用关系来提出的。

在这里插入图片描述
在这里插入图片描述

微服务:

在SOA基础上进一步解决架构复杂问题。微服务的拆分更细,针对于单一的服务进行更细致化的拆分,更轻量化,并通过更高级、更轻量的rest-api通信取代了ESB。

微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好地完成该任务。在所有情况下,每个任务代表着一个小的业务能力。

Docker技术

容器就是将软件打包成标准化单元,以用于开发、交付和部署。

Docker 是世界领先的软件容器平台

Java号称“一次编译,到处运行”,因为java虚拟机解决平台的兼容性问题,所以有java虚拟机的地方就能跑java代码;

Docker是:“一次封装,到处运行”,因为docker解决了应用环境的问题,安装了docker的平台就能跑“docker包”,这样就决绝了“开发环境能跑,一上线就崩”的尴尬。

Docker包含Image(镜像)、Container(容器)、Repository(仓库)

高可用

高可用(High availability)的主要目的是为了保障业务的连续性,即在用户眼里,业务永远是正常(或者说基本正常)对外提供服务的。

实现高可用基本思路

  • 注重代码质量、严格测试
  • 使用集群,减少单点故障
  • 超时和重试机制、熔断机制
  • 异步调用
  • 使用缓存
  • 提高硬件质量、定期检测维护等等等
前端FreeMarker模板

FreeMarker 是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

AdminLTE: Bootstrap 管理员仪表盘模板

AdminLTE 是一个完全响应管理模板,主要依赖于 Bootstrap 3、jQuery 1.11+ 这两个框架,插件中使用的基本都是Bootstrap和jQquery插件。

SpringBoot Actuator程序监控器

Spring Boot Actuator就是一款可以帮助你监控系统数据的框架,其可以监控很多很多的系统数据,它有对应用系统的自省和监控的集成功能,可以查看应用配置的详细信息,比如:

  • 显示应用程序员的Health健康信息
  • 显示Info应用信息
  • 显示HTTP Request跟踪信息
SpringBoot四大核心组件

自动配置Autoconfigure

起步依赖Starter

命令行界面CLI

监控器Actuator

MVNrepository官网

可以查询各种缺失的依赖:https://mvnrepository.com/

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/96097
推荐阅读
相关标签
  

闽ICP备14008679号