分布式定时调度XXL-JOB

XXL-JOB

背景:

任务调度是日常开发中非常常见的一个业务场景,我们经常需要去运行一些的周期性、指定时间点等方式自动触发的异步业务逻辑。
分布式定时调度XXL-JOB_第1张图片

集中式任务调度(单体)

  • while(true)+Thread.sleep
    • 轮询+线程休眠的方式实现定时任务;
  • java.util.Timer + java.util.TimerTask
    • Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,它可以计划多次执行一个任务。
    • TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务
  • ScheduledExecutorService
    • ScheduledExecutorService是从jdk1.5开始做为并发工具类被引入,缺点是不能指定具体的执行时间(需要自己写扩展),只能每隔多久执行一次。
  • Quartz
    • Quartz是一个开源的定时任务调度框架,由Java编写而成,用于Java生态下的定时任务调度,是一个灵活方便、使用简单的定时任务调度框架,可以和Spring整合使用。
  • Spring Task
    • Spring框架提供的轻量级的定时任务调用工具,使用方便。
  • Spring Boot注解 @EnableScheduling + @Scheduled
    • 底层依然是采用Spring Task;

分布式任务调度:

问题:
分布式集群的模式下,如果采用集中式的任务调度方式,会带来一些问题,比如:
1、多台机器集群部署的定时任务如何保证不被重复执行?
2、如何动态地调整定时任务的执行时间?(不重启服务的情况)
3、部署定时任务的机器发生故障如何实现故障转移?
4、如何对定时任务进行监控?
5、业务量比较大,单机性能的瓶颈问题,如何扩展?
等等问题
解决方案:
1、数据库唯一约束,避免定时任务重复执行(类似于分布式锁,插入成功执行,否则不执行);
2、使用配置文件:redis、mysql作为调度的开关(存入执行机器的ip);
3、使用分布式锁实现调度的控制;
4、使用分布式任务调度平台TBSchedule(淘宝)、Elastic-Job(当当)、Saturn(唯品会)、XXL-JOB(大众点评)、 Google Cron(谷歌)系统;
5、自研

原生定时任务框架存在的先天缺陷

1、不支持分片任务
  处理有序数据时,多机器分片执行任务处理不同数据
2、不支持生命周期统一管理
  不重启服务情况下关闭、启动任务。
3、不支持集群
  存在任务重复执行的问题
4、不支持失败重试
  出现异常后任务终结,不能根据执行状态控制任务重新执行
5、不支持动态调整
  不重启服务的情况下修改任务参数
6、无报警机制
  任务失败之后没有报警机制
7、任务数据统计难以统计
  任务数据量大时,对于任务执行情况无法高效的统计执行情况

XXL-JOB与Quartz对比

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

XXL-JOB概述:

美团开源的一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,例如:京东,优信二手车,北京尚德,360金融 (360),联想集团 (联想),易信 (网易)等等。
官网:http://www.xuxueli.com/xxl-job
Github:https://github.com/xuxueli/xxl-job

XXL-JOB框架:

分布式定时调度XXL-JOB_第2张图片
分布式定时调度XXL-JOB_第3张图片
服务端(调度中心):就是一个web管理后台
客户端(执行器):就是我们写的代码,这个代码里面执行定时任务的业务逻辑
心跳机制:
分布式定时调度XXL-JOB_第4张图片
RPC:
1、客户端client发起服务调用请求。
2、client stub 可以理解成一个代理,会将调用方法、参数按照一定格式进行封装,通过服务提供的地址,发起网络请求。
3、消息通过网络传输到服务端。
4、server stub接受来自socket的消息。
5、server stub将消息进行解包、告诉服务端调用的哪个服务,参数是什么。
6、结果返回给server stub。
7、sever stub把结果进行打包交给socket
8、socket通过网络传输消息。
9、client stub 从socket拿到消息。
10、client stub解包消息将结果返回给client。

XXL-JOB特性:

  • 简单:支持通过Web页面对任务进行CRUD操作,操作简单。
  • 动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效。
  • 注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址。
  • 故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
  • 任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务。
  • 分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务。
  • 邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件。等等

版本变化(2.3.0):

1、【新增】调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
2、【新增】触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 “固定间隔触发、(固定延时触发,实验中)” 新触发方式;
3、【新增】新增任务辅助工具 “XxlJobHelper”:提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等;
  3.1、“ShardingUtil” 组件废弃:改用 “XxlJobHelper.getShardIndex()/getShardTotal();” 获取分片参数;
  3.2、“XxlJobLogger” 组件废弃:改用 “XxlJobHelper.log” 进行日志输出;
4、执行器注册组件优化:注册逻辑调整为异步方式,提高注册性能;
5、任务核心类 “IJobHandler” 的 “execute” 方法取消出入参设计。改为通过 “XxlJobHelper.getJobParam” 获取任务参数并替代方法入参,通过 “XxlJobHelper.handleSuccess/handleFail” 设置任务结果并替代方法出参,示例代码如下:

@XxlJob("demoJobHandler")
public void execute() {
  String param = XxlJobHelper.getJobParam();    // 获取参数
  XxlJobHelper.handleSuccess();                 // 设置任务结果
}

6、任务调度生命周期重构:调度(schedule)、触发(trigger)、执行(handle)、回调(callback)、结束(complete);等等

XXL-JOB分布式任务调度平台实现

流程:
分布式定时调度XXL-JOB_第5张图片
1、从github(https://github.com/xuxueli/xxl-job)获取项目源码;
2、从源码中得到SQL脚本创建和初始化数据库;分布式定时调度XXL-JOB_第6张图片
分布式定时调度XXL-JOB_第7张图片
3、修改admin配置文件;
分布式定时调度XXL-JOB_第8张图片
分布式定时调度XXL-JOB_第9张图片
4、配置执行器
分布式定时调度XXL-JOB_第10张图片
在1号位置处配置修改:分布式定时调度XXL-JOB_第11张图片
2号位置处是执行器示例
5、运行项目访问:http://localhost:8080/xxl-job-admin/toLogin分布式定时调度XXL-JOB_第12张图片
用户名:admin
密码:123456
6、运行报表
分布式定时调度XXL-JOB_第13张图片
7、执行器注册
分布式定时调度XXL-JOB_第14张图片
8、任务配置
分布式定时调度XXL-JOB_第15张图片
分布式定时调度XXL-JOB_第16张图片

移植进入项目

1、pom添加依赖

<dependency>
	 <groupId>com.xuxueligroupId>
   <artifactId>xxl-job-coreartifactId>
   <version>2.3.0version>
dependency>

2、打包admin
3、移植config配置
分布式定时调度XXL-JOB_第17张图片
4、测试执行器
分布式定时调度XXL-JOB_第18张图片
移入项目成功

注意点

1、请添加图片描述
发生此问题是因为JDK版本过高,降低为1.8即可,但并不会影响使用
2、检查pom是否有以下依赖若没有运行会报错,请添加

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

集群
xxl-job-admin如果想实现Job集群需要实现:

  • DB配置一样
  • 登录账号一样
  • 集群机器时钟保持一致(单机集群忽略)

建议:推荐通过Nginx为调度中心集群做负载均衡,分配域名。调度中心访问、执行器回收配置、调用API服务等操作均通过该域名进行。
host文件配置
127.0.0.1 xxljob.mayikt.com
nginx配置

http {
    include       mime.types;
    default_type  application/octet-stream;
	
	upstream backserver {
		server 127.0.0.1:8080 weight=1;
		server 127.0.0.1:8081 weight=1;
	}
	
    server {
        listen       80;
        server_name  xxljob.mayikt.com;
 
        location / {
            proxy_pass   http://backserver;
            index  index.html index.htm;
        }
    }
}

xxl-job执行器配置文件
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin,http://127.0.0.1:8081/xxl-job-admin
xxl-job-admin,启动两个节点,端口分别为8080和8081
访问:http://xxljob.mayikt.com/xxl-job-admin
此时调度中心8080节点为主主节点,8081为从节点、
使用
浏览器访问nginx地址,转发到8080或8081 xxl-job-admin管理平台。
停掉8080主节点,此时调度中心到了8081备节点执行了。

你可能感兴趣的:(java,分布式,后端)