《分布式任务调度平台XXL_JOB》手册范本

合集下载

基于XXL-JOB的分布式定时任务研究和应用

基于XXL-JOB的分布式定时任务研究和应用

ComputerEraNo.620220引言随着业务场景变得越来越复杂,定时任务在程序设计中存在广泛应用。刚开始企业发展规模较小,业务范围有限,所以定时任务的需求也很少,这时定时任务可以直接在单台服务器节点上进行部署,而且基本不需要对这些任务进行控制和管理,任务也能顺利执行[1]。当然,这种方式会导致单点故障的问题,所以企业一般就会采用多台服务器节点进行备份来保证任务的成功执行。而随着企业的发展规模越来越大,业务逻辑愈加复杂,导致定时任务的需求量也在不断攀升。此时单个服务器节点已经无法承载众多定时任务同时执行,需要部署多台服务器节点来执行这些定时任务。而定时任务的调度问题也随之而来,首先

是定时任务的路由分配问题,即:应该由哪台服务器执行这个任务。其次是在分布式部署的情况下,定时任务的调度信息,执行状态的监控如何获取。由于同时部署在多台集群机器上,因此到达指定的定时时间时,多台机器上的定时器可能会同时启动,造成重复数据或者程序异常等问题。为了解决上述问题,市面上也诞生出了多种分布式事务解决方案,其中XXL-JOB便是其中之一。

1分布式定时任务对比1.1XXL-JOB简介XXL-JOB将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负

DOI:10.16644/j.cnki.cn33-1094/tp.2022.06.019基于XXL-JOB的分布式定时任务研究和应用

郑祥1,2,顾丹鹏1,2,陈肖勇1,2

(1.中国电建集团华东勘测设计研究院有限公司,浙江杭州311122;2.浙江华东工程数字技术有限公司)摘要:随着微服务架构成为主流,单体定时任务由于单点故障等问题渐渐无法满足平时的业务需求。分布式定时任务通过集群的方式进行管理调度,大大降低了开发和维护成本。通过分布式部署,保证了系统的高可用,伸缩性,提高了容错率。XXL-JOB拥有优秀的可视化界面,使用方便灵活高效。对比市场上的主流定时任务框架,基于XXL-JOB给出了一种分布式定时任务的解决方案,并在石坞实验室项目进行了部署和使用。关键词:微服务;分布式;定时任务;XXL-JOB中图分类号:TP399文献标识码:A文章编号:1006-8228(2022)06-80-03

SpringBoot整合Xxl-job实现定时任务的全过程

SpringBoot整合Xxl-job实现定时任务的全过程

SpringBoot整合Xxl-job实现定时任务的全过程⽬录前⾔⼀、部署调度中⼼1、项⽬下载2、初始化数据3、修改properties配置⽂件⼆、部署SpringBoot项⽬1、引⼊依赖2、创建配置类3、修改配置⽂件4、创建执⾏器5、启动SpringBoot项⽬三、通过调度中⼼进⾏任务调度1、添加执⾏器2、添加任务3、任务调度中⼼发起任务调度四、⼩结总结前⾔XXL-JOB是⼀个分布式任务调度平台,其核⼼设计⽬标是开发迅速、学习简单、轻量级、易扩展。

现已开放源代码并接⼊多家公司线上产品线,开箱即⽤。

如果是单机并且定时任务不多的情况,可以选择Timer注解@Scheduled或者Cron⼯具类等⽅式来实现,但是这有个缺点,那就是定时任务会写死在代码中,⼀旦启动,就不能暂停或者修改。

如果修改的话,整个还项⽬要重新编译,这属实⾮常的⿇烦。

本篇⽂章将会介绍如何通过xxl-job来实现任务的调度⼀、部署调度中⼼1、项⽬下载下⾯是调度中⼼代码的gitee地址,可以colon到本地/xuxueli0323/xxl-job2、初始化数据在下载好的项⽬中的doc/db⽬录下有⼀个tables_xxl_job.sql⽂件,先放到⾃⼰的数据库中执⾏,其实就是初始化好调度中⼼需要的表结构和数据3、修改properties配置⽂件⼆、部署SpringBoot项⽬1、引⼊依赖<dependency><groupId>com.xuxueli</groupId><artifactId>xxl-job-core</artifactId><version>2.2.0</version></dependency>2、创建配置类@Configurationpublic class XxlJobConfig {private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);@Value("${xxl.job.admin.addresses}")private String adminAddresses;@Value("${xxl.job.executor.appname}")private String appName;@Value("${xxl.job.executor.ip}")private String ip;@Value("${xxl.job.executor.port}")private int port;@Value("${xxl.job.accessToken}")private String accessToken;@Value("${xxl.job.executor.logpath}")private String logPath;@Value("${xxl.job.executor.logretentiondays}")private int logRetentionDays;@Beanpublic XxlJobSpringExecutor xxlJobExecutor() {(">>>>>>>>>>> xxl-job config init.");XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();xxlJobSpringExecutor.setAdminAddresses(adminAddresses);xxlJobSpringExecutor.setAppname(appName);xxlJobSpringExecutor.setIp(ip);xxlJobSpringExecutor.setPort(port);xxlJobSpringExecutor.setAccessToken(accessToken);xxlJobSpringExecutor.setLogPath(logPath);xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);return xxlJobSpringExecutor;}}3、修改配置⽂件xxl:job:admin:addresses: http://127.0.0.1:8080/xxl-job-admin #部署的调度中⼼的urlexecutor:appname: xxl-job-volunteer-executor #执⾏器的名字ip:port: 9999 #调度中⼼调⽤执⾏器时使⽤的端⼝logpath: /data/apploggs/xxl-job/jobhandler #⽇志路径logretentiondays: 30 #⽇志保留天数accessToken:4、创建执⾏器@Componentpublic class XxlJobSample {// myDemoJob是任务的名字,也是Spring中bean的名字@XxlJob("myDemoJob")public ReturnT<String> myDemoJob(String value) {System.out.println("myDemoJob:定时任务触发:" + value);return ReturnT.SUCCESS;}}5、启动SpringBoot项⽬启动成功后会看到下⾯两⾏⽇志信息,可以看到成功连接到了调度中⼼然后注册了将要被调度任务>>>>>>>>>>> xxl-job register jobhandler success, name:myDemoJob, jobHandler:com.xxl.job.core.handler.impl.MethodJobHandler@1f94dd63[class ponent.XxlJobSample#myDemoJob] >>>>>>>>>>> xxl-job remoting server start success, nettype = class com.xxl.job.core.server.EmbedServer, port = 9999三、通过调度中⼼进⾏任务调度1、添加执⾏器输⼊配置⽂件中配置的appName,名称可以随意2、添加任务新增调度任务查看调度任务3、任务调度中⼼发起任务调度在SpringBoot项⽬中可以看到控制台输出如下信息:2022-01-16 11:54:05.039 INFO 7836 --- [Pool-1148366645] c.xxl.job.core.executor.XxlJobExecutor : >>>>>>>>>>> xxl-job regist JobThread success, jobId:7, handler:com.xxl.job.core.handler.impl.MethodJobHandler@1f94dd63[class pone myDemoJob:定时任务触发:testParam2022-01-16 11:55:38.059 INFO 7836 --- [ Thread-22] com.xxl.job.core.thread.JobThread : >>>>>>>>>>> xxl-job JobThread stoped, hashCode:Thread[Thread-22,10,main]四、⼩结⾄此,SpringBoot整合Xxl-job就完成了,刚才的⽰例代码其实对于原来的项⽬还是有⼀定的侵⼊性的,上⾯仅仅演⽰了BEAN运⾏模式,说⽩了就是调⽤加了@XxlJob的⽅法。

xxl-job任务定时触发流程

xxl-job任务定时触发流程

xxl-job任务定时触发流程xxl-job任务触发流程xxl-job⽼版本是依赖quartz的定时任务触发,在v2.1.0版本开始移除quartz依赖:⼀⽅⾯是为了精简系统降低冗余依赖,另⼀⽅⾯是为了提供系统的可控度与稳定性。

(本⽂相应代码版本 2.2.0-SNAPSHOT)以下是本⽂的⽬录⼤纲:⼀.任务触发执⾏总体流程 ⼆.任务定时触发流程 三.关于这么设计的感悟请尊重作者劳动成果,转载请标明原⽂链接:⼀任务触发执⾏总体流程先来看下任务触发和执⾏的完整的任务触发执⾏总体流程图如下:上图所⽰左上⾓的第⼀步:任务触发⽅式主要有以下⼏种类型:1 根据设置的时间⾃动触发JobScheduleHelper,2 页⾯点击操作按钮执⾏触发,3 ⽗⼦任务触发,4失败重试触发。

本⽂重点讲解第⼀步:任务触发的第⼀种 1 根据设置的时间⾃动触发,即上图红⾊框内标⽰的部分,具体见JobScheduleHelper这个类。

⼆任务定时触发流程详细的JobScheduleHelperCron定时触发这个阶段流程图如下:具体见JobScheduleHelper这个类结合上⾯流程图来分析,在⼯程spring启动的时候触发了JobScheduleHelper类的start()⽅法,完整代码如下1public void start(){23// schedule thread4 scheduleThread = new Thread(new Runnable() {5 @Override6public void run() {78try {9 LISECONDS.sleep(5000 - System.currentTimeMillis()%1000 );10 } catch (InterruptedException e) {11if (!scheduleThreadToStop) {12 logger.error(e.getMessage(), e);13 }14 }15 (">>>>>>>>> init xxl-job admin scheduler success.");1617// pre-read count: treadpool-size * trigger-qps (each trigger cost 50ms, qps = 1000/50 = 20)18int preReadCount = (XxlJobAdminConfig.getAdminConfig().getTriggerPoolFastMax() + XxlJobAdminConfig.getAdminConfig().getTriggerPoolSlowMax()) * 20;1920while (!scheduleThreadToStop) {2122// Scan Job23long start = System.currentTimeMillis();2425 Connection conn = null;26 Boolean connAutoCommit = null;27 PreparedStatement preparedStatement = null;2829boolean preReadSuc = true;30try {3132 conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();33 connAutoCommit = conn.getAutoCommit();34 conn.setAutoCommit(false);3536 preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );37 preparedStatement.execute();3839// tx start4041// 1、pre read42long nowTime = System.currentTimeMillis();43 List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);44if (scheduleList!=null && scheduleList.size()>0) {45// 2、push time-ring46for (XxlJobInfo jobInfo: scheduleList) {4748// time-ring jump49if (nowTime > jobInfo.getTriggerNextTime() + PRE_READ_MS) {50// 2.1、trigger-expire > 5s:pass && make next-trigger-time51 logger.warn(">>>>>>>>>>> xxl-job, schedule misfire, jobId = " + jobInfo.getId());5253// fresh next54 refreshNextValidTime(jobInfo, new Date());5556 } else if (nowTime > jobInfo.getTriggerNextTime()) {57// 2.2、trigger-expire < 5s:direct-trigger && make next-trigger-time5859// 1、trigger60 JobTriggerPoolHelper.trigger(jobInfo.getId(), TriggerTypeEnum.CRON, -1, null, null);61 logger.debug(">>>>>>>>>>> xxl-job, schedule push trigger : jobId = " + jobInfo.getId() );6263// 2、fresh next64 refreshNextValidTime(jobInfo, new Date());6566// next-trigger-time in 5s, pre-read again67if (jobInfo.getTriggerStatus()==1 && nowTime + PRE_READ_MS > jobInfo.getTriggerNextTime()) {6869// 1、make ring second70int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);7172// 2、push time ring73 pushTimeRing(ringSecond, jobInfo.getId());7475// 3、fresh next76 refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));7778 }7980 } else {81// 2.3、trigger-pre-read:time-ring trigger && make next-trigger-time8283// 1、make ring second84int ringSecond = (int)((jobInfo.getTriggerNextTime()/1000)%60);8586// 2、push time ring87 pushTimeRing(ringSecond, jobInfo.getId());8889// 3、fresh next90 refreshNextValidTime(jobInfo, new Date(jobInfo.getTriggerNextTime()));9192 }9394 }9596// 3、update trigger info97for (XxlJobInfo jobInfo: scheduleList) {98 XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleUpdate(jobInfo);99 }100101 } else {102 preReadSuc = false;103 }104105// tx stop106107108 } catch (Exception e) {109if (!scheduleThreadToStop) {110 logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread error:{}", e);111 }112 } finally {113114// commit115if (conn != null) {116try {117 mit();118 } catch (SQLException e) {119if (!scheduleThreadToStop) {120 logger.error(e.getMessage(), e);121 }122 }123try {124 conn.setAutoCommit(connAutoCommit);125 } catch (SQLException e) {126if (!scheduleThreadToStop) {127 logger.error(e.getMessage(), e);128 }129 }130try {131 conn.close();132 } catch (SQLException e) {133if (!scheduleThreadToStop) {134 logger.error(e.getMessage(), e);135 }136 }137 }138139// close PreparedStatement140if (null != preparedStatement) {141try {142 preparedStatement.close();143 } catch (SQLException e) {144if (!scheduleThreadToStop) {145 logger.error(e.getMessage(), e);146 }147 }148 }149 }150long cost = System.currentTimeMillis()-start;151152153// Wait seconds, align second154if (cost < 1000) { // scan-overtime, not wait155try {156// pre-read period: success > scan each second; fail > skip this period;157 LISECONDS.sleep((preReadSuc?1000:PRE_READ_MS) - System.currentTimeMillis()%1000); 158 } catch (InterruptedException e) {159if (!scheduleThreadToStop) {160 logger.error(e.getMessage(), e);161 }162 }163 }164165 }166167 (">>>>>>>>>>> xxl-job, JobScheduleHelper#scheduleThread stop");168 }169 });170 scheduleThread.setDaemon(true);171 scheduleThread.setName("xxl-job, admin JobScheduleHelper#scheduleThread");172 scheduleThread.start();173174175// ring thread176 ringThread = new Thread(new Runnable() {177 @Override178public void run() {179180// align second181try {182 LISECONDS.sleep(1000 - System.currentTimeMillis()%1000 );183 } catch (InterruptedException e) {184if (!ringThreadToStop) {185 logger.error(e.getMessage(), e);186 }187 }188189while (!ringThreadToStop) {190191try {192// second data193 List<Integer> ringItemData = new ArrayList<>();194int nowSecond = Calendar.getInstance().get(Calendar.SECOND); // 避免处理耗时太长,跨过刻度,向前校验⼀个刻度;195for (int i = 0; i < 2; i++) {196 List<Integer> tmpData = ringData.remove( (nowSecond+60-i)%60 );197if (tmpData != null) {198 ringItemData.addAll(tmpData);199 }200 }201202// ring trigger203 logger.debug(">>>>>>>>>>> xxl-job, time-ring beat : " + nowSecond + " = " + Arrays.asList(ringItemData) );204if (ringItemData.size() > 0) {205// do trigger206for (int jobId: ringItemData) {207// do trigger208 JobTriggerPoolHelper.trigger(jobId, TriggerTypeEnum.CRON, -1, null, null);209 }210// clear211 ringItemData.clear();212 }213 } catch (Exception e) {214if (!ringThreadToStop) {215 logger.error(">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread error:{}", e);216 }217 }218219// next second, align second220try {221 LISECONDS.sleep(1000 - System.currentTimeMillis()%1000);222 } catch (InterruptedException e) {223if (!ringThreadToStop) {224 logger.error(e.getMessage(), e);225 }226 }227 }228 (">>>>>>>>>>> xxl-job, JobScheduleHelper#ringThread stop");229 }230 });231 ringThread.setDaemon(true);232 ringThread.setName("xxl-job, admin JobScheduleHelper#ringThread");233 ringThread.start();234 }View Code任务定时触发,流程如下:1 分布式锁为了保证分布式⼀致性先上悲观锁:使⽤select xx for update来实现1 conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection();2 connAutoCommit = conn.getAutoCommit();3 conn.setAutoCommit(false);4 preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" );5 preparedStatement.execute();2 轮询db,找出trigger_next_time(下次触发时间)在距now 5秒内的任务1 List<XxlJobInfo> scheduleList = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().scheduleJobQuery(nowTime + PRE_READ_MS, preReadCount);2详细sql如下:3 trigger_status代表触发状态处于启动的任务 trigger_next_time代表任务下次执⾏触发的时间4 <select id="scheduleJobQuery" parameterType="java.util.HashMap" resultMap="XxlJobInfo">5 SELECT *6 FROM xxl_job_info AS t7 WHERE t.trigger_status = 18 and t.trigger_next_time <![CDATA[ <= ]]> #{maxNextTime}9 ORDER BY id ASC10 LIMIT #{pagesize}11 </select>3 触发算法拿到了距now 5秒内的任务列表数据:scheduleList,分三种情况处理:for循环遍历scheduleList集合(1)对到达now时间后的任务:(超出now 5秒外):直接跳过不执⾏;重置trigger_next_time;(2)对到达now时间后的任务:(超出now 5秒内):线程执⾏触发逻辑;若任务下⼀次触发时间是在5秒内,则放到时间轮内(Map<Integer, List<Integer>> 秒数(1-60) => 任务id列表);再重置trigger_next_time(3)对未到达now时间的任务:直接放到时间轮内;重置trigger_next_time 。

.net分布式架构之任务调度平台

.net分布式架构之任务调度平台

.net分布式架构之任务调度平台开源地址:.net 任务调度平台⽤于.net dll,exe的任务的挂载,任务的隔离,调度执⾏,访问权限控制,监控,管理,⽇志,错误预警,性能分析等。

1) 平台基于进⾏任务调度功能开发,采⽤C#代码编写, ⽀持corn表达式和第三⽅⾃定义的corn表达式扩展。

2) 架构以插件形式开发,具有良好的功能扩展性,稳定性,简单性,便于第三⽅开发⼈员进⼀步进⾏功能扩展。

3) ⽀持多节点集群,便于集群服务器的资源有效分配,任务的相互隔离。

4) ⽀持邮件形式的错误预警,便于运维及时处理任务异常等。

开源相关群: .net 开源基础服务 238543768任务demousing System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Dyd.BaseService.TaskManager.Demo{///<summary>///任务调度平台任务插件的写法demo及说明///</summary>public class DemoTask : XXF.BaseService.TaskManager.BaseDllTask{///<summary>///任务调度平台根据发布的任务时间配置,定时回调运⾏⽅法///开发⼈员的任务插件必须要重载并该⽅法///</summary>public override void Run(){/** this.OpenOperator ⽤于任务调度平台提供给第三⽅使⽤的所有api接⼝封装*//*获取当前任务dll安装⽬录*/this.OpenOperator.GetTaskInstallDirectory();/*打印⼀条⽇志到任务调度平台,因为⽇志会存到平台数据库,所以⽇志要精简,对任务出错时有分析价值【注意:不要频繁打印⽆⽤的,⾮必要的,对分析⽆价值的⽇志信息】*/this.OpenOperator.Log("这⾥打印⼀条⽇志到任务调度平台");/*打印⼀条错误到任务调度平台,因为⽇志会存到平台数据库,所以⽇志要精简,对任务出错时有分析价值【注意:不要频繁打印⽆⽤的,⾮必要的,对分析⽆价值的⽇志信息】*后续任务会有增加优先级区分,根据任务的优先级,错误的出现频率等,错误⽇志会定期推送到开发者邮箱和短信*/this.OpenOperator.Error("这⾥打印⼀条错误⽇志到任务调度平台", new Exception("错误msg信息"));/*从数据库获取任务的临时数据,临时数据以jason的形式保存在数据库⾥⾯,便于任务上下⽂的恢复和信息传递【注意:不应⽤于"频繁的"存储"⼤量的"临时数据,会操作⽹络耗时和数据库性能差】*/ var databasetempinfo = this.OpenOperator.GetDataBaseTempData<DemoTaskDatabaseTempInfo>();if (databasetempinfo == null)//若任务第⼀次运⾏,可能没有临时数据。

分布式定时任务

分布式定时任务

分布式定时任务任务调度场景概述在平时的业务场景中,经常有⼀些场景需要使⽤定时任务。

时间驱动的场景某个时间点发送优惠券,发送短信等等⽣成报表爬⾍(定点爬取某排⾏榜信息)批量处理数据批量统计上个⽉的账单,统计上个⽉销售数据等等。

固定频率的场景每隔 5 分钟需要执⾏⼀次。

为什么需要任务调度平台在 Java 中,传统的定时任务实现⽅案,⽐如 Timer,Quartz 等,缺点:不⽀持集群、不⽀持统计、没有管理平台、没有失败报警、没有监控等等,分布式的架构中,有⼀些场景需要分布式任务调度,同⼀个服务多个实例的任务存在互斥时,需要统⼀的调度,任务调度需要⽀持⾼可⽤、监控、故障告警。

需要统⼀管理和追踪各个服务节点任务调度的结果,需要记录保存任务属性信息等。

什么是分布式任务调度任务调度是指基于给定的时间点,给定的时间间隔或者给定执⾏次数⾃动的执⾏任务。

任务调度是是操作系统的重要组成部分,⽽对于实时的操作系统,任务调度直接影响着操作系统的实时性能。

任务调度涉及到多线程并发、运⾏时间规则定制及解析、线程池的维护等诸多⽅⾯的⼯作。

任务调度框架⾮分布式在单⼀服务器当中,创建定时任务,@Scheduled。

分布式把分散的,可靠性差的计划任务纳⼊统⼀的平台,并实现集群管理调度和分布式部署的⼀种定时任务的管理⽅式,叫做分布式定时任务Quartz先驱者⽆图形化界⾯接⼝不⼈性化Elasticjob基于 Quartzelastic-job 是由当当⽹基于 Quartz ⼆次开发之后的分布式调度解决⽅案依赖很多中间件 zkxxl-job美团点评⾥⾯开发者开发出来的SchedulerX阿⾥云出的⼀个框架商⽤产品PowerJob个⼈对⽐:@Scheduled 创建⼯程:使⽤ @Scheduled 添加注解创建 JobTest.java:/*** @author BNTang* @version 1.0* @project distributed-TimedTask* @description* @since Created in 2021/10/5 005 22:00**/@Slf4j@Component@EnableSchedulingpublic class JobTest {@Scheduled(fixedDelayString = "3000", initialDelay = 5000)public void work() throws InterruptedException {("work任务开始!");Thread.sleep(5000);}}启动之后运⾏效果如下图所⽰:@EnableScheduling:是否要开启 Scheduled 也可以加在启动类上,整个项⽬⽣效,@Scheduled 注解中属性的取值的含义,fixedDelayString、fixedDelay 代表固定延时,要等上⼀次任务结束时,下⼀次才开始计时,initialDelay 代表延迟启动。

简述分布式任务调度

简述分布式任务调度
E-Job :通过事件订阅方式可自行实现。 作业运行状态监控、监听作业服务器存活、监听近期数据处理成功、数据流类型作业
(可通过监听近期数据处理成功数判断作业流量是否正常,如果小于作业正常处理的阀值,可选择报警。)、 监听近期数据处理失败(可通过监听近期数据处理失败数判断作业处理结果,如果大于0,可选择报警。)
第贰章
有哪些分布式任务调度框架
第 贰 章
Quartz集群
上图三个节点在数据库中都拥有同一份Job定义,如果某一个节点失效,那 么Job会在其他节点上执行。由于三个节点上的Job执行代码是一样的,那 么怎么保证只有在一台机器上触发呢?答案是使用了数据库锁。在quartz 的集群解决方案里有张表scheduler_locks,quartz采用了悲观锁的方式 对triggers表进行行加锁,以保证任务同步的正确性。一旦某一个节点上 面的线程获取了该锁,那么这个Job就会在这台机器上被执行,同时这个锁 就会被这台机器占用。同时另外一台机器也会想要触发这个任务,但是锁 已经被占用了,就只能等待,直到这个锁被释放。之后会看trigger状态, 如果已经被执行了,则不会执行了。
地址:/xxl-job
TBSchedule
淘宝开源的分布式任务调度 框架。广泛应用于阿里巴巴、 淘宝、支付宝、京东、聚美、 汽车之家、国美等很多互联 网企业的流程调度系统。
Uncode-Schedule
基于zookeeper的分布式任 务调度组件,非常小巧,使 用简单,只需要引入jar包, 不需要单独部署服务端。确 保所有任务在集群中不重复, 不遗漏的执行。支持动态添 加和删除任务。

第壹章
为什么需要分布式任务调度
高可用问题
单机版的定式任务调度只能在 一台机器上运行,如果程序或 者系统出现异常就会导致功能 不可用。虽然可以在单机程序 实现的足够稳定,但始终有机 会遇到非程序引起的故障,而 这个对于一个系统的核心功能 来说是不可接受的。

xxl-job原理

xxl-job原理

xxl-job原理
XXL-JOB是一款轻量级开源的分布式任务调度框架,xxl-job节点划分为"执行器"与"调度器"两大模块,服务间无状态,执行器与调度器可以异机部署。

执行器是一种基本的任务执行服务,执行器上的任务是以"插件化"的方式,通过java jar文件部署在执行器上,当调度器需要请求执行任务时,执行器就会将任务部署在指定的机器上执行。

调度器通过RESTful API(REST非对称API)向下游提供服务,调度器可以根据不同的应用需求,自定义调度任务的触发时机,比如一秒执行一次,一小时执行一次,每分钟执行一次等,同时也可以支持定时,定点,指定间隔执行,秒级任务、分级任务、小时级任务,日级任务等等。

XXL-JOB还支持分布式、HA部署,多台服务器节点间互相通信,扩展性也很强,可以扩展更多更复杂的特性,如URL参数调度、多租户数据分隔等。

XXL-JOB还支持任务调度的"可视化配置"管理,便于操作人员将任务部署到不同的执行器上,以流程的方式进行管理,让运维的任务更加轻松和高效。

另外,XXL-JOB还提供了用户可视化端,可以根据任务的运行状态、任务的运行时间等信息,以及实时任务的监控,便于用户对任务进行更好的管理,快速找出任务出现的问题,以实现自动化管理。

xxljob分片原理

xxljob分片原理

xxljob分片原理XXLJob是一款分布式作业调度系统,它可以实现分片作业,可以有效地提高工作效率,解决大型复杂作业调度问题。

本文将详细介绍XXLJob分片原理,带领大家了解XXLJob分片调度技术。

1、XXLJob分片介绍XXLJob分片,也称分片调度,是一种用于对工作进行分片的调度技术。

它可以将一个大型的或者复杂的作业拆分成多个工作片段,每一个片段都可以单独调度和执行,从而实现工作的并行处理。

XXLJob分片主要用于批量数据处理和其他计算任务,它可以高效地处理大量数据和高容量任务,降低工作量和完成任务的时间。

XXLJob分片调度技术支持多种作业类型,如实时作业、定时作业、周期性作业等,它的主要特点是将单个作业拆分成多个片段,支持多种数据源,提供可靠的作业调度服务,支持多台机器调度,可以实现跨机器的分布式作业处理,分片数量可配置,支持拆分结果反馈,进程安全性等。

2、XXLJob分片原理XXLJob分片原理可以分为两部分:拆分原理和调度原理。

拆分原理:在XXLJob分片原理中,拆分作业是指将一个大型的或者复杂的作业拆分成多个片段,每一个片段可以单独调度和执行,从而实现作业的并行处理。

XXLJob拆分原理基于数据类型,由数据源提供数据,不同的数据源拆分算法也不同,例如,如果数据源是数据库,可以通过计算每个分片范围的数据量来实现拆分;而如果数据源是文件,则可以通过计算文件大小以及分片数量来实现拆分。

调度原理:在XXLJob分片原理中,调度原理指的是将作业拆分成多个片段后,如何对片段进行调度和执行。

XXLJob调度原理分为三种模式:调度模式、执行模式和结果反馈模式。

调度模式:即在调度系统中根据作业参数进行调度,调度系统可以根据作业参数的不同分配不同的调度机器,从而实现跨机器分布式作业处理。

执行模式:即根据调度结果,在调度机器上执行作业。

调度机器可以根据片段数量进行并发执行,从而实现分片作业的并行处理,在整个作业执行完后,调度机器还可以将每个片段的执行结果进行汇总,完成最终调度结果的收集和处理。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《分布式任务调度平台XXL-JOB》手册文档历史记录
目录
1:简介 (3)
2:安装 (3)
3:配置 (3)
3.1数据库准备 (4)
3.2源码准备 (5)
3.3部署准备 (5)
3.3.1 配置部署“调度中心” (5)
3.3.2 配置部署“执行器项目” (7)
4:使用 (9)
步骤一:新建任务 (9)
步骤二:“GLUE模式(Java)”任务开发 (10)
步骤三:触发执行 (10)
步骤四:查看日志 (10)
5:总结 (11)
1:简介
XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展,XXL-JOB是基于开源Quartz 调度核的、为方便企业调度场景而开源的一款实用的调度工具。

自带任务配置页面,任务监控,分布式执行器等功能。

2:安装
下载地址(最新1.9版本迭代中,可选择稳定版本1.8.2下载)
码云:https://gitee./xuxueli0323/xxl-job/tree/v1.8.2
3:配置
解压下载文件,得到如下文件结构,
- /doc :文档资料
- /db :“调度数据库”建表脚本
- /xxl-job-admin :调度中心,项目源码
- /xxl-job-core :公共Jar依赖
- /xxl-job-executor-samples :执行器,Sample示例项目
3.1数据库准备
使用mysql 新建数据库xxl-job ,导入下载文件夹中/doc/db/tables_xxl_job.sql 文件,应生成16表,如图所示。

3.2源码准备
按照maven格式将源码导入IDE,使用maven进行编译即可,源码结构如下
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
:xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用;
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器;
:xxl-job-executor-sample-jfinal:JFinal版本,通过JFinal管理执行器;
:xxl-job-executor-sample-nutz:Nutz版本,通过Nutz管理执行器;
3.3部署准备
3.3.1 配置部署“调度中心”
调度中心项目:xxl-job-admin
作用:统一管理任务调度平台上调度任务,负责触发调度执行,并且提供任务管理平台。

步骤一:调度中心配置
文件地址:
/xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties,数据库连接地址与上面所创建数据库的地址要一致。

步骤二:部署项目
可将项目编译的war包部署到tomcat中,现将war部署到192.168.110.2 服务器上将war包复制到 /root/apache-tomcat-7.0.78/webapps 目录下。

启动tomc at,游览器输入 192.168.110.2:8080/xxl-job-admin/
3.3.2 配置部署“执行器项目”
“执行器”项目:xxl-job-executor-sample-spring (提供多种版本执行器供选择,现以Spring 版本为例,可直接使用,也可以参考其并将现有项目改造成执行器)
作用:负责接收“调度中心”的调度并执行;可直接部署执行器,也可以将执行器集成到现有业务项目中。

步骤一:maven依赖
确认pom文件中引入了"xxl-job-core" 的maven依赖;
步骤二:执行器配置
文件地址:
/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-spring/src/main/resources/xxl-job-executor.properties 如tomcat端口占用,可将xxl.job.executor.port改成9888
步骤三:执行器组件配置
文件地址:
/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-spring/src/main/resources/appli cationcontext-xxl-job.xml
步骤四:部署执行器项目
同“调度中心”war一致复制到/root/apache-tomcat-7.0.78/webapps 目录下,启动tomcat
4:使用
本示例以新建一个“GLUE模式(Java)” 运行模式的任务为例。

(“GLUE模式(Java)”的执行代码托管到调度中心在线维护,相比“Bean模式任务”需要在执行器项目开发部署上线,更加简便轻量)
前提:请确认“调度中心”和“执行器”项目已经成功部署并启动;
步骤一:新建任务
登录调度中心,点击下图所示“新建任务”按钮,新建示例任务。

然后,参考下面截图中任务的参数配置,点击保存,Cron表达式,例如0 0/1 * * * ? 每一分钟执行一次。

步骤二:“GLUE模式(Java)”任务开发
请点击任务右侧“GLUE” 按钮,进入“GLUE编辑器开发界面” ,见下图。

“GLUE模式(Java)” 运行模式的任务默认已经初始化了示例任务代码,即打印“XXL-JOB, Hello World. 2018-03-27/xuya”
步骤三:触发执行
请点击任务右侧“执行” 按钮,可手动触发一次任务执行
步骤四:查看日志
请点击任务右侧“日志” 按钮,可前往任务日志界面查看任务日志。

在任务日志界面中,可查看该任务的历史调度记录以及每一次调度的任务调度信息、执行参数和执行信息。

运行中的任务点击右侧的“执行日志”按钮,可进入日志控制台查看实时执行日志。

在日志控制台,可以Rolling 方式实时查看任务在执行器一侧运行输出的日志信息,实时监控任务进度;
5:总结 XXL-JOB 将调度行为抽象形成
“调度中心
”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。

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

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

附上XXL-JOB 架构图:。

相关文档
最新文档