一文读懂分布式任务调度平台XXL-JOB

基本介绍

项目开发中,经常如下场景须要分布式任务调度:git

  • 同一服务多个实例的任务存在互斥时,须要统一协调github

  • 定时任务的执行须要支持高可用、监控运维、故障告警数据库

  • 须要统一管理和追踪各个服务节点定时任务的运行状况,以及任务属性信息,例如任务所属服务、所属责任人网络

所以,XXL-JOB应运而生:XXL-JOB是一个开源的轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展、开箱即用,其中“XXL”是主要做者,大众点评许雪里名字的缩写自2015年开源以来,已接入数百家公司的线上产品线,接入场景涉及电商业务,O2O业务和大数据做业等多线程

功能特性

主要功能特性以下:app

  • 简单灵活提供Web页面对任务进行管理,管理系统支持用户管理、权限控制;支持容器部署;支持经过通用HTTP提供跨平台任务调度;
  • 丰富的任务管理功能支持页面对任务CRUD操做;支持在页面编写脚本任务、命令行任务、Java代码任务并执行;支持任务级联编排,父任务执行结束后触发子任务执行;支持设置任务优先级;支持设置指定任务执行节点路由策略,包括轮询、随机、广播、故障转移、忙碌转移等;支持Cron方式、任务依赖、调度中心API接口方式触发任务执行
  • 高性能调度中心基于线程池多线程触发调度任务,快任务、慢任务基于线程池隔离调度,提供系统性能和稳定性;任务调度流程全异步化设计实现,如异步调度、异步运行、异步回调等,有效对密集调度进行流量削峰;
  • 高可用任务调度中心、任务执行节点均 集群部署,支持动态扩展、故障转移支持任务配置路由故障转移策略,执行器节点不可用是自动转移到其余节点执行 支持任务超时控制、失败重试配置 支持任务处理阻塞策略:调度当任务执行节点忙碌时来不及执行任务的处理策略,包括:串行、抛弃、覆盖策略
  • 易于监控运维支持设置任务失败邮件告警,预留接口支持短信、钉钉告警;支持实时查看任务执行运行数据统计图表、任务进度监控数据、任务完整执行日志;
系统设计

1 设计思路

将调度行为抽象造成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求;将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑;所以,“调度”和“任务”两部分能够相互解耦,提升系统总体稳定性和扩展性;运维

2 系统组成

  • 调度模块(调度中心)负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提升了系统可用性和稳定性,同时调度系统性能再也不受限于任务模块;支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,任务报警等,全部上述操做都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover


  • 执行模块(执行器)负责接收调度请求并执行任务逻辑。任务模块专一于任务的执行等操做,开发和维护更加简单和高效;接收“调度中心”的执行请求、终止请求和日志请求等



3 工做原理


  • 任务执行器根据配置的调度中心的地址,自动注册到调度中心
  • 达到任务触发条件,调度中心下发任务
  • 执行器基于线程池执行任务,并把执行结果放入内存队列中、把执行日志写入日志文件中
  • 执行器的回调线程消费内存队列中的执行结果,主动上报给调度中心
  • 当用户在调度中心查看任务日志,调度中心请求任务执行器,任务执行器读取任务日志文件并返回日志详情

4 HA设计

4.1 调度中心高可用

调度中心支持多节点部署,基于数据库行锁保证同时只有一个调度中心节点触发任务调度,参考com.xxl.job.admin.core.thread.JobScheduleHelper#start异步

 
 
  1. Connection 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();



  6. # 触发任务调度



  7. # 事务提交


  8. conn.commit();


4.2 任务调度高可用

  • 路由策略 调度中心基于路由策略路由选择一个执行器节点执行任务,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)


使用

1 快速上手

具体如何快速上手使用,官方文档:http://www.xuxueli.com/xxl-job/ 已经介绍得比较详细和清楚,再也不赘述分布式

2 注意事项

  • 1 时钟同步问 调度中心和任务执行器须要时间同步,同步时间偏差须要在3分钟内,不然抛出异常 参考:com.xxl.rpc.remoting.provider.XxlRpcProviderFactory#invokeService
 
 
  1. if (System.currentTimeMillis() - xxlRpcRequest.getCreateMillisTime() > 3*60*1000) {ide


  2.    xxlRpcResponse.setErrorMsg("The timestamp difference between admin and executor exceeds the limit.");


  3.    return xxlRpcResponse;

  4. }


  • 2 时区问题任务由调度中心触发,按照在调度中心设置任务的cron表达式触发时,须要注意部署调度中心的机器所在的时区,按照该时区定制化cron表达式


  • 3 任务执行中服务宕掉问题调度中心完成任务下发,执行器在执行任务的过程当中,若是执行器忽然服务宕掉,会致使任务的执行问题在调度中心是执行中,调度中心并不会发起失败重试。即便任务设置了超时时间,执行器宕掉致使致使任务长时间未执行完成,调度中心界面也不会看到任务超时,由于任务超时是由执行器检测的并上报给调度中心的

所以遇到任务长时间未执行完成,能够关注是否发生了执行器忽然服务宕掉

  • 4 优雅停机问题执行器执行任务基于线程池异步执行,当须要重启时须要注意线程池中还有未执行完成任务的问题,须要优雅停机,能够直接基于XxlJobExecutor.destroy()优雅停机,注意该方法在v2.0.2以前的版本存在bug致使没法优雅停机,v2.0.2及以后的版本才修复(参考:https://github.com/xuxueli/xxl-job/issues/727)


  • 5 失败重试问题当执行器节点部分服务不可用,例如节点磁盘损坏,但在调度中心仍然处于在线时,调度中心仍可能基于路由策略(包括故障转移策略)路由到该未下线的节点,并不断重试,不断失败,致使重试次数耗尽。因此路由策略尽可能不要采用固定化策略(例如固定第一个、固定最后一个策略)


总结

XXL-JOB上手仍是比较简单,项目源码仍是比较整洁,容易读懂,学习以后能够更加深刻理解分布式系统设计、网络通讯、多线程协同处理等知识点,推荐阅读

相关文章
相关标签/搜索