本文主要介绍分布式任务调度平台XXL-JOB(v2.1.0版本),包括功能特性、实现原理、优缺点、同类框架比较等mysql
项目开发中,经常如下场景须要分布式任务调度:git
所以,XXL-JOB应运而生: XXL-JOB是一个开源的轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展、开箱即用,其中“XXL”是主要做者,大众点评许雪里名字的缩写github
自2015年开源以来,已接入数百家公司的线上产品线,接入场景涉及电商业务,O2O业务和大数据做业等spring
主要功能特性以下:sql
简单灵活 提供Web页面对任务进行管理,管理系统支持用户管理、权限控制; 支持容器部署; 支持经过通用HTTP提供跨平台任务调度;数据库
丰富的任务管理功能 支持页面对任务CRUD操做; 支持在页面编写脚本任务、命令行任务、Java代码任务并执行; 支持任务级联编排,父任务执行结束后触发子任务执行; 支持设置任务优先级; 支持设置指定任务执行节点路由策略,包括轮询、随机、广播、故障转移、忙碌转移等; 支持Cron方式、任务依赖、调度中心API接口方式触发任务执行bash
高性能 调度中心基于线程池多线程触发调度任务,快任务、慢任务基于线程池隔离调度,提供系统性能和稳定性; 任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰;服务器
高可用 任务调度中心、任务执行节点均 集群部署,支持动态扩展、故障转移 支持任务配置路由故障转移策略,执行器节点不可用是自动转移到其余节点执行 支持任务超时控制、失败重试配置 支持任务处理阻塞策略:调度当任务执行节点忙碌时来不及执行任务的处理策略,包括:串行、抛弃、覆盖策略markdown
易于监控运维 支持设置任务失败邮件告警,预留接口支持短信、钉钉告警; 支持实时查看任务执行运行数据统计图表、任务进度监控数据、任务完整执行日志;网络
将调度行为抽象造成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求; 将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑; 所以,“调度”和“任务”两部分能够相互解耦,提升系统总体稳定性和扩展性;
调度模块(调度中心): 负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提升了系统可用性和稳定性,同时调度系统性能再也不受限于任务模块; 支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,任务报警等,全部上述操做都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover
执行模块(执行器): 负责接收调度请求并执行任务逻辑。任务模块专一于任务的执行等操做,开发和维护更加简单和高效; 接收“调度中心”的执行请求、终止请求和日志请求等
调度中心支持多节点部署,基于数据库行锁保证同时只有一个调度中心节点触发任务调度,参考com.xxl.job.admin.core.thread.JobScheduleHelper#start
Connection conn = XxlJobAdminConfig.getAdminConfig().getDataSource().getConnection(); connAutoCommit = conn.getAutoCommit(); conn.setAutoCommit(false); preparedStatement = conn.prepareStatement( "select * from xxl_job_lock where lock_name = 'schedule_lock' for update" ); preparedStatement.execute(); # 触发任务调度 # 事务提交 conn.commit(); 复制代码
路由策略 调度中心基于路由策略路由选择一个执行器节点执行任务,XXL-JOB提供了以下路由策略保证任务调度高可用: 忙碌转移策略: 下发任务前向执行器节点发起rpc心跳请求查询是否忙碌,若是执行器节点返回忙碌则转移到其余执行器节点执行(参考 com.xxl.job.admin.core.route.strategy.ExecutorRouteBusyover) 故障转移策略: 下发任务前向执行器节点发起rpc心跳请求查询是否在线,若是执行器节点没返回或者返回不可用则转移到其余执行器节点执行 (参考com.xxl.job.admin.core.route.strategy.ExecutorRouteFailover)
阻塞处理策略 当执行器节点存在多个相同任务id的任务未执行完成,则须要基于阻塞策略对任务进行取舍: 串行策略:默认策略,任务进行排队、丢弃旧任务策略、丢弃新任务策略 (参考:com.xxl.job.core.biz.impl.ExecutorBizImpl#run)
特性 | quartz | elastic-job-lite | xxl-job | LTS |
---|---|---|---|---|
依赖 | MySQL、jdk | jdk、zookeeper | mysql、jdk | jdk、zookeeper、maven |
高可用 | 多节点部署,经过竞争数据库锁来保证只有一个节点执行任务 | 经过zookeeper的注册与发现,能够动态的添加服务器 | 基于竞争数据库锁保证只有一个节点执行任务,支持水平扩容。能够手动增长定时任务,启动和暂停任务,有监控 | 集群部署,能够动态的添加服务器。能够手动增长定时任务,启动和暂停任务。有监控 |
任务分片 | × | √ | √ | √ |
管理界面 | × | √ | √ | √ |
难易程度 | 简单 | 简单 | 简单 | 略复杂 |
高级功能 | - | 弹性扩容,多种做业模式,失效转移,运行状态收集,多线程处理数据,幂等性,容错处理,spring命名空间支持 | 弹性扩容,分片广播,故障转移,Rolling实时日志,GLUE(支持在线编辑代码,免发布),任务进度监控,任务依赖,数据加密,邮件报警,运行报表,国际化 | 支持spring,spring boot,业务日志记录器,SPI扩展支持,故障转移,节点监控,多样化任务执行结果支持,FailStore容错,动态扩容。 |
版本更新 | 半年没更新 | 2年没更新 | 最近有更新 | 1年没更新 |
具体如何快速上手使用,官方文档:www.xuxueli.com/xxl-job/ 已经介绍得比较详细和清楚,再也不赘述
if (System.currentTimeMillis() - xxlRpcRequest.getCreateMillisTime() > 3*60*1000) { xxlRpcResponse.setErrorMsg("The timestamp difference between admin and executor exceeds the limit."); return xxlRpcResponse; } 复制代码
2 时区问题 任务由调度中心触发,按照在调度中心设置任务的cron表达式触发时,须要注意部署调度中心的机器所在的时区,按照该时区定制化cron表达式
3 任务执行中服务宕掉问题 调度中心完成任务下发,执行器在执行任务的过程当中,若是执行器忽然服务宕掉,会致使任务的执行问题在调度中心是执行中,调度中心并不会发起失败重试。即便任务设置了超时时间,执行器宕掉致使致使任务长时间未执行完成,调度中心界面也不会看到任务超时,由于任务超时是由执行器检测的并上报给调度中心的
所以遇到任务长时间未执行完成,能够关注是否发生了执行器忽然服务宕掉
4 优雅停机问题 执行器执行任务基于线程池异步执行,当须要重启时须要注意线程池中还有未执行完成任务的问题,须要优雅停机,能够直接基于XxlJobExecutor.destroy()优雅停机,注意该方法在v2.0.2以前的版本存在bug致使没法优雅停机,v2.0.2及以后的版本才修复(参考:github.com/xuxueli/xxl…)
5 失败重试问题 当执行器节点部分服务不可用,例如节点磁盘损坏,但在调度中心仍然处于在线时,调度中心仍可能基于路由策略(包括故障转移策略)路由到该未下线的节点,并不断重试,不断失败,致使重试次数耗尽。因此路由策略尽可能不要采用固定化策略,例如固定第一个、固定最后一个
XXL-JOB上手仍是比较简单,项目源码仍是比较整洁,容易读懂,学习以后能够更加深刻理解分布式系统设计、网络通讯、多线程协同处理等知识点,推荐阅读