分布式任务调度

目前任务调度在项目中的问题

  1. 由于接三方渠道越来越多,越来越多的定制化定时任务
  2. 目前定时任务没有集中管理,相对比较分散
  3. 跑批任务现在是单点执行,目前没有做分片执行,其实可以通过mq方式。但是还是存在单点再跑,如果节点没有被调度成功,跑批任务就跪了

业界主流开源

  1. elastic job(http://elasticjob.io/)
  2. xxl-job(https://github.com/xuxueli/xxl-job)
  3. quartz(http://www.quartz-scheduler.org/)

调度项目对比

对比项quartzelastic jobxxl-job
可用性(HA)支持,通过数据库锁方式支持支持通过数据库锁
管理台支持,单不完善支持,功能相对完善
分片不支持支持支持
社区活跃活跃停止维护几年国内活跃,还在升级维护
任务唤醒不支持支持
任务监控自己扩展不支持支持邮件,调度日志
技术复杂性简单相对复杂,需要zookeeper(适合已有zookeeper项目)简单,调度中心+执行器(server+client方式)

调研结果

  1. 目前公司使用quartz 基于数据库集群模式
  2. 因为目前公司没有用zookeeper,假如是dubbo项目的话,可能就用elastic-job
  3. xxl-job 支持任务串行调用
  4. 社区的活跃程度偏向xxl-job

了解xxl-job

xxl-job 总体分为两个部分调度中心和执行器

xxl-job 调度中心

  1. 负责任务的调度,不做具体业务的处理
  2. 存储基于mysql
  3. 记录调度日志
  4. 调度器和执行器之间netty通讯,实际还是http
  5. xxl-job 2.0 版本之后删除了quartz 依赖,具体原因不明,因为quartz依赖只会放到调度中心里,不会在具体执行器里依赖
  6. 充当执行器注册中心
  7. xxl-job 调度中心集群,通过数据库锁的方式,避免重复调度,集群是两个完全互补感知的机器,通过nginx upstream + 域名方式来保证可用性
  8. 为支持不同环境配置及配置集中管理,基于2.1.2 源码集成了nacos配置中心
  9. xxl-job 定时任务是通过时间轮的方式实现,将快执行的数据放到时间轮里,另外一个线程从时间轮里获取将要执行的任务进行调度,具体原理见图:

xxl-job executor 执行器

  1. 执行器启动服务时,把包含@jobHandler bean 放到concurrenyMap中
  2. 注册自己的ip和端口到调度中心
  3. 启动netty server 为调度中心提供接口调度支持
  4. 接受调度中心任务调度,从concurrentyMap 中拿去对应任务执行,异步返回调度成功
  5. 任务执行后,将调度结果回调调度单中心

xxl-job 结构相关图整理

xxl-job 整体类流程图

项目迁移中碰到的问题

  1. xxl-job 版本 2.1.2 由于2.2.0 升级到了spring boot 2.0,目前项目是1.5.x 所以使用2.1.2
  2. spring boot 1.5.x 或者说spring cloud 版本中的netty依赖和robbion中的netty依赖冲突,xxl-job 执行器自己实现了netty-server,netty 版本较新,目前robbion没有用到netty,走的http协议,所以把robbion中的netty依赖排除。
  3. 为了保证不重复执行,任务执行开始和结束都会有分布式锁,测试中发现一个问题,任务如果是分片广播模式,分布式锁是基于任务名称,所以有一台会获取不到锁,这里针对分布式锁,增加了分片信息。

项目部署结构图