xxl-Job分布式任务调度 1

简介: xxl-Job分布式任务调度

1.概述

1.1 什么是任务调度

我们可以先思考一下业务场景的解决方案:

某电商系统需要在每天上午10点,下午3点,晚上8点发放一批优惠券。

某银行系统需要在信用卡到期还款日的前三天进行短信提醒。

某财务系统需要在每天凌晨0:10结算前一天的财务数据,统计汇总。

12306会根据车次的不同,设置某几个时间点进行分批放票。

某网站为了实现天气实时展示,每隔10分钟就去天气服务器获取最新的实时天气信息。

以上业务场景的解决方案就是任务调度。


任务调度是指系统为了自动完成特定任务,在约定的特定时刻去执行任务的过程。有了任务调度即可解放更多的人力,而是由系统自动去执行任务。


如何实现任务调度?


多线程方式,结合sleep

JDK提供的API,例如:Timer、ScheduledExecutor

框架,例如Quartz ,它是一个功能强大的任务调度框架,可以满足更多更复杂的调度需求

spring-task

但是上述这些解决方案要么实现起来比较繁琐,要么不能满足分布式架构需求,我们需要更好的解决方案。


入门案例


spring-task为spring框架自带的定时任务模块


1快速构建创程spring-task-demo


20210217121548593.png


2启动类上加注解 @EnableScheduling


3创建定时任务类

package com.example.demo.job;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class HelloJob {
    @Scheduled(cron = "0/5 * * * * *")
    public void task(){
        System.out.println("干活了!"+new Date());
    }
}

4启动程序


1.2 cron表达式

cron表达式是一个字符串, 用来设置定时规则, 由七部分组成, 每部分中间用空格隔开, 每部分的含义如下表所示:

组成部分 含义 取值范围
第一部分 Seconds (秒) 0-59
第二部分 Minutes(分) 0-59
第三部分 Hours(时) 0-23
第四部分 Day-of-Month(天) 1-31
第五部分 Month(月) 0-11或JAN-DEC
第六部分 Day-of-Week(星期) 1-7(1表示星期日)或SUN-SAT
第七部分 Year(年) 可选 1970-2099
符号 含义
? 表示不确定的值。当两个子表达式其中一个被指定了值以后,为了避免冲突,需要将另外一个的值设为“?”。例如:想在每月20日触发调度,不管20号是星期几,只能用如下写法:0 0 0 20 * ?,其中最后以为只能用“?”
* 代表所有可能的值
, 设置多个值,例如”26,29,33”表示在26分,29分和33分各自运行一次任务
- 设置取值范围,例如”5-20”,表示从5分到20分钟每分钟运行一次任务
/ 设置频率或间隔,如"1/15"表示从1分开始,每隔15分钟运行一次任务
L 用于每月,或每周,表示每月的最后一天,或每个月的最后星期几,例如"6L"表示"每月的最后一个星期五"
W 表示离给定日期最近的工作日,例如"15W"放在每月(day-of-month)上表示"离本月15日最近的工作日"
# 表示该月第几个周X。例如”6#3”表示该月第3个周五





为了让大家更熟悉cron表达式的用法, 接下来我们给大家列举了一些例子, 如下表所示:

cron表达式 含义
*/5 * * * * ? 每隔5秒运行一次任务
0 0 23 * * ? 每天23点运行一次任务
0 0 1 1 * ? 每月1号凌晨1点运行一次任务
0 0 23 L * ? 每月最后一天23点运行一次任务
0 26,29,33 * * * ? 在26分、29分、33分运行一次任务
0 0/30 9-17 * * ? 朝九晚五工作时间内每半小时运行一次任务
0 15 10 ? * 6#3 每月的第三个星期五上午10:15运行一次任务

1.3 什么是分布式任务调度

当前软件的架构已经开始向分布式架构转变,将单体结构拆分为若干服务,服务之间通过网络交互来完成业务处理。在分布式架构下,一个服务往往会部署多个实例来运行我们的业务,如果在这种分布式系统环境下运行任务调度,我们称之为分布式任务调度。


20210217121607875.png


将任务调度程序分布式构建,这样就可以具有分布式系统的特点,并且提高任务的调度处理能力:


1、并行任务调度


并行任务调度实现靠多线程,如果有大量任务需要调度,此时光靠多线程就会有瓶颈了,因为一台计算机CPU的处理能力是有限的。


如果将任务调度程序分布式部署,每个结点还可以部署为集群,这样就可以让多台计算机共同去完成任务调度,我们可以将任务分割为若干个分片,由不同的实例并行执行,来提高任务调度的处理效率。


2、高可用


若某一个实例宕机,不影响其他实例来执行任务。


3、弹性扩容


当集群中增加实例就可以提高并执行任务的处理效率。


4、任务管理与监测


对系统中存在的所有定时任务进行统一的管理及监测。让开发人员及运维人员能够时刻了解任务执行情况,从而做出快速的应急处理响应。


分布式任务调度面临的问题:


当任务调度以集群方式部署,同一个任务调度可能会执行多次,例如:电商系统定期发放优惠券,就可能重复发放优惠券,对公司造成损失,信用卡还款提醒就会重复执行多次,给用户造成烦恼,所以我们需要控制相同的任务在多个运行实例上只执行一次。常见解决方案:


分布式锁,多个实例在任务执行前首先需要获取锁,如果获取失败那么就证明有其他服务已经在运行,如果获取成功那么证明没有服务在运行定时任务,那么就可以执行。

ZooKeeper选举,利用ZooKeeper对Leader实例执行定时任务,执行定时任务的时候判断自己是否是Leader,如果不是则不执行,如果是则执行业务逻辑,这样也能达到目的。

1.4 xxl-Job简介

针对分布式任务调度的需求,市场上出现了很多的产品:


1) TBSchedule:淘宝推出的一款非常优秀的高性能分布式调度框架,目前被应用于阿里、京东、支付宝、国美等很多互联网企业的流程调度系统中。但是已经多年未更新,文档缺失严重,缺少维护。


2) XXL-Job:大众点评的分布式任务调度平台,是一个轻量级分布式任务调度平台, 其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。


3)Elastic-job:当当网借鉴TBSchedule并基于quartz 二次开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,具有任务高可用以及分片功能。


4)Saturn: 唯品会开源的一个分布式任务调度平台,基于Elastic-job,可以全域统一配置,统一监

控,具有任务高可用以及分片功能。


XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。


源码地址:https://gitee.com/xuxueli0323/xxl-job


文档地址:https://www.xuxueli.com/xxl-job/


特性


简单:支持通过Web页面对任务进行CRUD操作,操作简单,一分钟上手;

动态:支持动态修改任务状态、启动/停止任务,以及终止运行中任务,即时生效;

调度中心HA(中心式):调度采用中心式设计,“调度中心”自研调度组件并支持集群部署,可保证调度中心HA;

执行器HA(分布式):任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA;

注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址;

弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;

路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、一致性HASH、最不经常使用、最近最久未使用、故障转移、忙碌转移等;

故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。

阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行(默认)、丢弃后续调度、覆盖之前调度;

任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务;

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

任务失败告警;默认提供邮件方式失败告警,同时预留扩展接口,可方便的扩展短信、钉钉等告警方式;

分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;

动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。

事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。

任务进度监控:支持实时监控任务进度;

Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志;

GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。支持30个版本的历史版本回溯。

脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS、PHP、PowerShell等类型脚本;

命令行任务:原生提供通用命令行任务Handler(Bean任务,“CommandJobHandler”);业务方只需要提供命令行即可;

任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔;

一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行;

自定义任务参数:支持在线配置调度任务入参,即时生效;

调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞;

数据加密:调度中心和执行器之间的通讯进行数据加密,提升调度信息安全性;

邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件;

推送maven中央仓库: 将会把最新稳定版推送到maven中央仓库, 方便用户接入和使用;

运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等;

全异步:任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰,理论上支持任意时长任务的运行;

跨平台:原生提供通用HTTP任务Handler(Bean任务,“HttpJobHandler”);业务方只需要提供HTTP链接即可,不限制语言、平台;

国际化:调度中心支持国际化设置,提供中文、英文两种可选语言,默认为中文;

容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用;

线程池隔离:调度线程池进行隔离拆分,慢任务自动降级进入"Slow"线程池,避免耗尽调度线程,提高系统稳定性;

用户管理:支持在线管理系统用户,存在管理员、普通用户两种角色;

权限控制:执行器维度进行权限控制,管理员拥有全量权限,普通用户需要分配执行器权限后才允许相关操作;

2.XXL-Job快速入门

在分布式架构下,通过XXL-Job实现定时任务


20210217121628574.png


2.1 环境搭建

2.1.1 调度中心环境要求

Maven3+

Jdk1.8+

Mysql5.7+

2.1.2 源码仓库地址

也可以使用资料文件夹中的源码


2.1.3 初始化“调度数据库”

请下载项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可。

位置:/xxl-job/doc/db/tables_xxl_job.sql 共8张表

调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例;

如果mysql做主从,调度中心集群节点务必强制走主库;

2.1.4 编译源码

解压源码,按照maven格式将源码导入IDE, 使用maven进行编译即可,源码结构如下:

目录
相关文章
|
3月前
|
存储 NoSQL 调度
|
5月前
|
NoSQL Java 调度
在Spring Boot中实现分布式任务调度
在Spring Boot中实现分布式任务调度
|
5月前
|
设计模式 存储 缓存
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
Java面试题:结合建造者模式与内存优化,设计一个可扩展的高性能对象创建框架?利用多线程工具类与并发框架,实现一个高并发的分布式任务调度系统?设计一个高性能的实时事件通知系统
64 0
|
5月前
|
NoSQL Java 调度
在Spring Boot中实现分布式任务调度
在Spring Boot中实现分布式任务调度
|
6月前
|
调度
自己动手实现分布式任务调度框架(续)(2)
自己动手实现分布式任务调度框架(续)
|
6月前
|
消息中间件 负载均衡 Java
自己动手实现分布式任务调度框架(续)(1)
自己动手实现分布式任务调度框架(续)
|
7月前
|
分布式计算 Java 调度
[Java 探索者之路] 一个大厂都在用的分布式任务调度平台
[Java 探索者之路] 一个大厂都在用的分布式任务调度平台
|
7月前
|
SQL 调度 数据库
Docker部署Xxl-Job分布式任务调度中心(超详细)
Docker部署Xxl-Job分布式任务调度中心(超详细)
|
7月前
|
分布式计算 Ubuntu 调度
如何本地搭建开源分布式任务调度系统DolphinScheduler并远程访问
如何本地搭建开源分布式任务调度系统DolphinScheduler并远程访问
262 0
|
2月前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
下一篇
DataWorks