方案对比
image

 

1、quartz

   quartz的集群方案是使用数据库来实现的。通过在数据库中配置定时器信息, 以数据库悲观锁的方式达到同一个任务始终只有一个节点在运行。

 「项目地址:https://github.com/quartz-scheduler/quartz

 「go的开源实现:https://github.com/reugn/go-quartz

 

1.1 架构

  集群架构如下:

image-1691055079624

  上图三个节点在数据库中都拥有同一份Job定义,如果某一个节点失效,那么Job会在其他节点上执行。

   由于三个节点上的Job执行代码是一样的,那么怎么保证只有在一台机器上触发呢?答案是使用了数据库锁。

  在quartz的集群解决方案里有张表scheduler_locks,quartz采用了「悲观锁」的方式对triggers表进行行加锁,以保证任务同步的正确性。一旦某一个节点上面的线程获取了该锁,那么这个Job就会在这台机器上被执行,同时这个锁就会被这台机器占用。同时另外一台机器也会想要触发这个任务,但是锁已经被占用了,就只能等待,直到这个锁被释放。之后会看trigger状态,如果已经被执行了,则不会执行了。

   简单地说,quartz的分布式调度策略是以数据库为边界资源的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性。同时多个节点的异步运行保证了服务的可靠。但这种策略有自己的局限性:集群特性对于高CPU使用率的任务效果很好,但是对于大量的短任务,各个节点都会抢占数据库锁,这样就出现大量的线程等待资源。这种情况随着节点的增加会越来越严重。

 

1.2 优缺点

优点:

  1. 保证节点高可用 (HA), 如果某一个几点挂了, 其他节点可以顶上

缺点:

  1. 同一个任务只能有一个节点运行,其他节点将不执行任务,性能低,资源浪费
  2. 当碰到大量短任务时,各个节点频繁的竞争数据库锁,节点越多这种情况越严重。性能会很低下
  3. quartz 的分布式仅解决了集群高可用的问题,并没有解决任务分片的问题,不能实现水平扩展

 

2、elastic-job

   elastic-job 是由当当网基于quartz 二次开发之后的分布式调度解决方案 , 由两个相对独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成 。

   Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。一般我们只要使用Elastic-Job-Lite就好。

「项目地址:https://github.com/dangdangdotcom/elastic-job

 

2.1 架构

   Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。

   Elastic-Job-Cloud使用Mesos + Docker(TBD)的解决方案,额外提供资源治理、应用分发以及进程隔离等服务

 

2.2 优缺点

优点:

  1. 基于quartz 定时任务框架为基础的,因此具备quartz的大部分功能

  2. 使用zookeeper做协调,调度中心,更加轻量级

  3. Elastic-Job-Lite并没有宿主程序,而是基于部署作业框架的程序在到达相应时间点时各自触发调度。它的开发也比较简单,引用Jar包实现一些方法即可,最后编译成Jar包运行。

  4. Elastic-Job-Lite的分布式部署全靠ZooKeeper来同步状态和原数据。实现高可用的任务只需将分片总数设置为1,并把开发的Jar包部署于多个服务器上执行,任务将会以1主N从的方式执行。一旦本次执行任务的服务器崩溃,其他执行任务的服务器将会在下次作业启动时选择一个替补执行。如果开启了失效转移,那么功能效果更好,可以保证在本次作业执行时崩溃,备机之一立即启动替补执行。

  5. Elastic-Job-Lite的任务分片也是通过ZooKeeper来实现,Elastic-Job并不直接提供数据处理的功能,框架只会将分片项分配至各个运行中的作业服务器,开发者需要自行处理分片项与真实数据的对应关系。框架也预置了一些分片策略:平均分配算法策略,作业名哈希值奇偶数算法策略,轮转分片策略。同时也提供了自定义分片策略的接口。

  6. Elastic-Job-Lite还提供了一个任务监控和管理界面:Elastic-Job-Lite-Console。它和Elastic-Job-Lite是两个完全不关联的应用程序,使用ZooKeeper来交换数据,管理人员可以通过这个界面查看、监控和管理Elastic-Job-Lite的任务,必要的时候还能手动触发任务。

    关注的是数据,增加了弹性扩容和数据分片的思路,以便于更大限度的利用分布式服务器的资源。但是学习成本相对高些,推荐在“数据量庞大,且部署服务器数量较多”时使用。

   elastic-job结合了quartz非常优秀的时间调度功能,并且利用ZooKeeper实现了灵活的分片策略。除此之外,还加入了大量实用的监控和管理功能,以及其开源社区活跃、文档齐全、代码优雅等优点,是分布式任务调度框架的推荐选择。

缺点:

  1. 引入的依赖较多,会增加系统的复杂度。

 

3、xxl-job

   xxl-job是由个人开源的一个轻量级分布式任务调度框架 ,主要分为调度中心和执行器两部分,调度中心在启动初始化的时候,会默认生成执行器的RPC代理。

   对象(http协议调用), 执行器项目启动之后, 调度中心在触发定时器之后通过jobHandle 来调用执行器项目里面的代码,核心功能和elastic-job差不多,同时技术文档比较完善。

「项目地址: https://github.com/xuxueli/xxl-job

 

3.1 架构

image-1691055103864

  调度中心通过获取DB锁来保证集群中执行任务的唯一性。

 

3.2 优缺点

优点:

  1. 文档比较详细,xxl-job分为调度中心(中心式)和执行器(分布式),调度中心基于集群Quartz实现并支持集群部署,可保证调度中心HA;任务分布式执行,任务"执行器"支持集群部署,可保证任务执行HA,其中调度中心集群基于DB,而其他两个框架用zookeeper崃实现分布式锁。
  2. 侧重的业务实现的简单和管理的方便,学习成本简单,失败策略和路由策略丰富。推荐使用在“用户基数相对少,服务器数量在一定范围内”的情景下使用,版本更新较快也是其一大亮点,支持子任务,DAG任务和依赖任务已经列入TODOLIST,暂时不支持秒任务,具体支持如下:
  3. 支持多种语言作业,语言无关(Java/Go/C++/PHP/Python/Ruby/shell)
  4. 分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;
  5. 动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
  6. 支持作业高可用
  7. 弹性扩容缩容:一旦有新执行器机器上线或者下线,下次调度时将会重新分配任务;
  8. 故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
  9. 事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。
  10. 任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔;
  11. 容器化:提供官方docker镜像,并实时更新推送dockerhub,进一步实现产品开箱即用;
  12. 任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;其中分片任务支持分片粒度的失败重试;

 
缺点:

  1. 短时任务多时,数据库的锁竞争激烈,影响性能

 

4、Saturn

  Saturn是唯品会在github开源的一款分布式任务调度产品。它是基于当当elastic-job 1.0版本来开发的,其上完善了一些功能和添加了一些新的feature。

「 项目地址:https://github.com/vipshop/Saturn

 

4.1 架构

Saturn包括两大部分,Saturn ConsoleSaturn Executor

  • Saturn Console是一个GUI,用于作业/Executor管理,统计报表展现,系统配置等功能。它同时也是整个调度系统的大脑:将作业任务分配到各Executor。

    为了实现Console的高可用性,我们都希望Console有多台服务器所组成。我们只需要在多台不同的服务器的环境变量中指定相同的VIP_SATURN_CONSOLE_CLUSTER即可,至于VIP_SATURN_CONSOLE_CLUSTER的值,由你自行指定,只是一个集群标识而已。

  • Saturn Executor是执行任务的Worker:按照作业配置的要求去执行部署于Executor所在容器或物理机当中的作业脚本和代码。

 

4.2 优缺点

优点:

  1. 支持基于事件和时间触发
  2. 支持多种语言作业,语言无关(Java/Go/C++/PHP/Python/Ruby/shell)
  3. 支持秒级调度
  4. 支持作业分片并行执行
  5. 支持依赖作业串行执行
  6. 支持作业高可用和智能负载均衡
  7. 支持异常检测和自动失败转移
  8. 支持异地容灾
  9. 支持多个集群部署
  10. 支持跨机房区域部署
  11. 支持弹性动态扩容
  12. 支持优先级和权重设置
  13. 支持docker容器,容器化友好
  14. 支持cron时间表达式
  15. 支持多个时间段暂停执行控制
  16. 支持超时告警和超时强杀控制
  17. 支持灰度发布
  18. 支持异常、超时和无法高可用作业监控告警和简易的故障排除
  19. 支持失败率最高、最活跃和负荷最重的各域各节点TOP10的作业统计
  20. 支持简单的DAG任务和依赖任务
  21. 可视化管理

 

缺点:

  1. 技术文档较少 , 该框架是2016年由唯品会的研发团队基于elastic-job开发而来的

 

5、antares

5.1 架构

image-1691055125591

5.2 优缺点

优点:

  1. 一个任务仅会被服务器集群中的某个节点调度,调度机制基于成熟的 quartz
  2. 并行执行 , 用户可通过对任务预分片,有效提升任务执行效率
  3. 失效转移
  4. 弹性扩容,在任务运行时,可以动态的加机器
  5. 友好的管理控制台

 
缺点:

  1. 不能动态的添加任务,仅能在控制台对任务进行触发,暂停,删除等操作
  2. 文档不多,开源社区不够活跃

 

6、opencron

   opencron是 一个功能完善真正通用的linux定时任务调度定系统,满足多种场景下各种复杂的定时任务调度,同时集成了linux实时监控,webssh,提供一个方便管理定时任务的平台。

 

6.1 优缺点

优点:

  • 自动化管理任务,提供可操作的web图形化管理
  • 时间规则支持quartz和crontab,更强大更灵活
  • 任务的运行状态实时查看
  • 支持任务kill(包括由当前任务调起的其他子任务链,彻底kill)
  • 支持重新执行正在运行的任务
  • 出错后实时通知给任务人(超过重跑次数自动发送邮件,短信)
  • 支持任务超时设置,一旦超过预定运行时长自动kill,任务结束,防止僵尸任务
  • 支持流程任务(多台机器上协同完成一个大的任务,按任务分配的顺序依次执行每台机器上的任务)
  • 记录任务的运行日志,非常方便查看
  • 多用户多角色
  • 提供服务器的性能实时监控

 

缺点:

  1. 仅支持 kill任务,现场执行,查询任务运行状态等,主要功能是着重于任务的修改和查询上。
  2. 不能动态的添加任务以及任务分片。

 
 
参考链接:
https://www.cnblogs.com/haoxinyue/p/6886196.html
https://blog.csdn.net/weixin_39605894/article/details/110982518
https://www.cnblogs.com/rainswinds/p/10930495.html
https://blog.csdn.net/taosir_zhang/article/details/50728362
 
如有不对,烦请指出,感谢~