精华内容
下载资源
问答
  • 作业即定时任务。一般来说,系统可使用消息传递代替部分使用作业的场景。两者确有相似之处。可互相替换的场景,如队列表。...时间驱动OR事件驱动:内部系统一般可以通过事件来驱动,但涉及到外部系统,则只能
  • 分布式作业调度框架,是一个开发迅速、学习简单、轻量级、易扩展、高可用分布式任务调度框架。 二、分布式任务调度框架 2.1 任务调度框架的简介 任务调度是指基于给定的时间点,给定的时间间隔或者给定执行次数...

    一、前言

    分布式大行其下的时代,让大家彻底的抛弃了传统陈旧的技术框架。几乎每一个技术人都知道和掌握了微服务架构,微服务自然有它的美,但是所以技术框架都必须服务于业务,结合自身业务选取甚至自研适合自身的技术框架也是技术人必须首先考虑的事情。分布式作业调度框架,是一个开发迅速、学习简单、轻量级、易扩展、高可用分布式任务调度框架。

    二、分布式任务调度框架

    2.1 任务调度框架的简介

    任务调度是指基于给定的时间点,给定的时间间隔或者给定执行次数自动的执行任务。任务调度涉及到多线程并发、运行时间规则定制及解析、线程池的维护等诸多方面的工作。

    • 同一服务多个实例的任务存在互斥时,需要统一协调
    • 定时任务的执行需要支持高可用、监控运维、故障告警
    • 需要统一管理和追踪各个服务节点定时任务的运行情况,以及任务属性信息,例如任务所属服务、所属责任人

    2.2 常见分布式任务调度框架

    目前主流的分布式作业调度平台,主要有:当当网开源项目Elastic-job、大众点评开源项目xxl-job、唯品会开源项目Saturn、阿里巴巴早期开源项目TBSchedule等。

    2.3 实现原理

    Java有个标准定时任务Quartz,它的关注点在于定时任务而非数据,并无一套根据数据处理而定制化的流程。虽然Quartz可以基于数据库实现作业的高可用,但缺少分布式并行调度的功能。

    分布式任务调度框架,就是基于Quartz的理念,支持任务动态分片、集群部署、轻量级易上手的分布式定时作业调度架构。

    详细查看另一篇文章,专门介绍Saturn:唯品会开源分布式作业调度平台Saturn

    三、分布式微服务框架

    3.1 微服务框架的简介

    官方对于微服务并没有一个详细的定义,最初是有从传统的单体式应用架构,可以做垂直于水平拆分而衍生出的一种架构理念。于是,分布式微服务技术就因运而生了。一个去中心化的多业务独立部署和运维的SOA(面向服务的架构)集群。

    3.2 主流的微服务框架

    目前主流的微服务框架有:国外开源项目SpringCloud、阿里巴巴开源项目Dubbo和SpringCloudAlibaba(基于SpringCloud)、新浪微博Motan、腾讯开源项目Tars等。

    国内用的最多的框架是SpringCloud和Dubbo,详细查看另一篇文章:SpringCloud与Dubbo的比较

    3.3 原理简介

    简单来说,微服务就是一种将一个单一应用程序拆分为一组小型服务的方法,拆分完成后,每一个服务都运行在独立的进程中,服务于服务之间采用轻量级的通信机制来进行沟通(Spring Cloud 中采用基于HTTP 的 RESTful API)。

    微服务可以理解为是 SOA (面向服务的体系结构) 的一个传承,一个本质的区别是微服务是一个真正分布式、去中心化的,微服务的拆分比 SOA 更加彻底。

    微服务的优势

    1. 复杂度可控

    2. 独立部署

    3. 技术选型灵活

    4. 较好的容错性

    5. 较强的可扩展性

    四、任务调度和微服务的区别

    4.1 对比

    任务调度:可用于精确至时分秒定时执行的作业,可重复执行,可动态设置分片参数来设置任务的并发大小数。

    1、轻量级,支持通过Web页面对任务进行动态CRUD操作,操作简单,一分钟上手,这点应该都差不多
    2、只依赖数据库作为集群注册中心,接入开发简单,不需要ZK
    3、高可用、解耦、高性能、监控报警、分片、重试、故障转移
    4、团队持续开发
    5、支持后台直接查看每个任务执行实时日志

    微服务:去中心化,基于业务拆分的某个独立部署和运行的模块,高可用高扩展。

    ●单一职责原则

    指的是每一个微服务模块,只关心自己的业务规则。例如订单模块只关心订单的相关业务,不牵扯其他业务的逻辑。

    ●服务自治原则

    每一个微服务模块的开发,需要有自己的开发、测试、运维、部署这一条独立的栈,并且有自己的数据库等一切,完全把其当成一个单独的项目来做,不牵扯到其它无关业务。

    ●轻量级通信原则

    微服务的通信协议需要跨平台、跨语言的通信协议,因为微服务是不绑定技术栈的,不论使用Java、PHP还是.net去开发Web系统,它们之间的通信一定是去语言特色的。

    ●接口明确原则

    前面提到了微服务的“接口调整成本高”,那么怎么去避免它呢?我们一开始就应该规划好微服务的模块是一种什么样的模型,尽量去避免A接口的改动会导致B接口的改动这种情况。

    五、总结

    技术框架没有好坏之分,只有适合于不适合的概念。基于各自业务和场景,选择适合的技术框架是每一个技术人必须要首先考虑的事情。业务驱动技术,技术为业务服务,每一个伟大的技术架构的诞生都是从业务本身抽象和发展而来。随着时代的发展,先进的技术架构必然淘汰陈旧的技术框架。保持持续学习的热情和心态才能让我们跟随科技发展的脚步。


    既然都看完了整篇文章,相信对你一定有所帮助。原创不易,勿做伸手党。

    点击下方【打赏】小编,或者关注公众号给予支持,你们的每一份鼓励都将是小编伟大的动力。


    同名原创公众号:  程序大视界

     

    展开全文
  • 分布式调度框架大集合

    万次阅读 多人点赞 2018-09-15 18:03:31
    分布式任务调度框架 1、什么是分布式任务调度? 2、常见的分布式任务调度框架有哪些? 3、分布式任务调度框架的技术选型? 4、分布式任务调度框架的安装与使用? 大对比表格:...

    分布式任务调度框架

    1、什么是分布式任务调度?

    2、常见的分布式任务调度框架有哪些?

    3、分布式任务调度框架的技术选型?

    4、分布式任务调度框架的安装与使用?

    大对比表格:https://pan.baidu.com/s/1CZAjTFqIhinzlVLnrrMUKQ

    分布式任务调度,三个关键词:分布式、任务调度、配置中心。

    分布式:平台是分布式部署的,各个节点之间可以无状态和无限的水平扩展;

    任务调度:涉及到任务状态管理、任务调度请求的发送与接收、具体任务的分配、任务的具体执行;(这里又会遇到一共要处理哪些任务、任务要分配到哪些机器上处理、任务分发的时候判断哪些机器可以用等问题,所以又需要一个可以感知整个集群运行状态的配置中心)

    配置中心:可以感知整个集群的状态、任务信息的注册

    一个分布式任务调度系统需要以下内容:

    web模块、server模块、Scheduler模块、worker模块、注册中心。

    1Web模块:用来提供任务的信息,控制任务的状态、信息展示等。

    2Server模块:负责接收web端传来的任务执行的信息,下发任务调度请求给Scheduler,会去注册中心进行注册

    3Scheduler模块:接收server端传来的调度请求,将任务进行更加细化的拆分然后下发,到注册中心进行注册,获取到可以干活的worker

    4Worker模块:负责具体的任务执行。

    5、注册中心。

     

     

     

     

     

     

     

    1、什么是分布式任务调度?

    任务调度是指基于给定的时间点,给定的时间间隔或者给定执行次数自动的执行任务。任务调度是是操作系统的重要组成部分,而对于实时的操作系统,任务调度直接影响着操作系统的实时性能。任务调度涉及到多线程并发、运行时间规则定制及解析、线程池的维护等诸多方面的工作。

    WEB服务器在接受请求时,会创建一个新的线程服务。但是资源有限,必须对资源进行控制,首先就是限制服务线程的最大数目,其次考虑以线程池共享服务的线程资源,降低频繁创建、销毁线程的消耗;然后任务调度信息的存储包括运行次数、调度规则以及运行数据等。一个合适的任务调度框架对于项目的整体性能来说显得尤为重要。

    2、常见的任务调度框架有哪些?

    我们在实际的开发工作中,或多或少的都会用到任务调度这个功能。常见的分布式任务调度框架有:cronsun、Elastic-job、saturn、lts、TBSchedule、xxl-job等。

    2.1cronsun

    crontab是Linux系统里面最简单易用的定时任务管理工具,在Linux上由crond来周期性的执行指令列表,执行的任务称为cron job,多个任务就称为crontab。crontab任务调度指令的基本格式为:

     

    *    *    *   *    *    command

                      命令

     

    但是时间久了之后会发现,crontab会存在一些问题:

    1. 大量的crontab分散在各台服务器,带来了很高的维护成本;
    2. 任务没有按时执行,过了很长的时间才能发现,需要重试或者排查;
    3. crontab分散在很多集群上,需要一台一台的去查看日志;
    4. crontab存在单点问题,对于不能重复执行的定时任务很伤脑;
    5. ……

    因此非常需要一个集中管理定时任务的系统,于是就有了cronsun。cronsun是一个分布式任务系统,单个节点和Linux机器上的contab近似,是为了解决多台Linux机器上crontab任务管理不方便的问题,同时提供了任务高可用的支持(当某个节点死机的时候可以自动调整到正常的节点执行)。与此同时,它还支持界面管理机器上的任务,支持任务失败邮件提醒,安装简单,使用简便,是替换crontab的一个不错的选择。

    cronsun中主要有三个组件,都是通过etcd通讯的。cronnode负责节点的分组及节点的状态,cronweb是用来管理任务的、任务的执行结果都可以在上面看。

    cronsun的系统架构如下图所示,简单的来说就是,所有的任务都会存储在一个分布式etcd里,单个crond部署成一个服务,也就是图中所示的node.1、node.2、node.n等,然后再由web界面去管理。如果任务执行失败的话,会发送失败的邮件,当单个节点死机的时候,也会自动调整到正常的节点去执行任务。

    cronsun是在管理后台添加任务的,所以一旦管理后台泄漏出去了,则存在一定的危险性,所以cronsun支持security.json的安全设置:

     {
    "open": true,
    "#users": "允许选择运行脚本的用户", "users": [
    "www", "db" ],
    "#ext": "允许添加以下扩展名结束的脚本", "ext": [
    ".cron.sh", ".cron.py" ]
    }

        如以上设置开启安全限制,则添加和执行任务的时候只允许选择配置里面指定的用户来执行脚本,并且脚本的扩展名要在配置的脚本的扩展名限制的列表里面。

    2.2、Elastic-job

    Elastic-job是当当开源的一款非常好用的作业框架,Elastic-job在2.x之后,出现了两个相互独立的产品线:Elastic-job-lite和Elastic-job-cloud。

    2.2.1、Elastic-job-lite

       Elastic-job-lite定位为轻量级无中心化的解决方案,使用jar包的形式提供分布式任务的协调服务,外部依赖仅依赖于zookeeper。

        Elastic-job-lite的架构图如下图所示:

    从上面的框架图中可以看出,Elastic-job-lite框架使用zookeeper作为注册中心,Elastic-job-lite框架通过监听感知zookeeper数据的变化,并做相应的处理;运维平台也仅是通过读取zk数据来展现作业状态,或是更新zk数据修改全局配置。运维平台和Elastic-job-lite没有直接的关系,完全解耦合。Elastic-job-lite并不直接提供数据处理的功能,框架只会将分片项分配给各个正在运行中的服务器,分片项与真是数据的对应关系需要开发者在应用程序中自行处理。

    Elastic-job-lite并无作业调度中心节点,而是基于部署作业框架的程序在到达相应时间点时各自触发调度。注册中心仅用于作业注册和监控信息存储,而主作业节点仅用于处理分片和清理的功能。

    (1)注册中心的数据结构

            我们先来了解一下该框架在zookeeper上的节点情况。首先注册中心在命名的空间下创建作业名称节点(作业名称用来区分不同的作业,一旦修改名称,则认为是新的作业),作业名称节点下又包含5个子节点:

    config:保存作业的配置信息,以JSON格式存储

    sharding:保存作业的分片信息,它的子节点是分片项序号,从零开始,至分片总数减一

    leader:该节点保存作业服务器主节点的信息,分为election、sharding和failover三个子节点,分别用于主节点的选举、分片和失效转移

    instances:该节点保存的是作业运行实例的信息,子节点是当前作业运行实例的主键

    servers:该节点保存作业服务器的信息,子节点是作业服务器的IP地址

    (2)实现原理

    1. 第一台服务器上线触发主服务器选举,主服务器一旦下线,则重新触发选举,选举过程中阻塞,只有当主服务器选举完成,才会去执行其他的任务;
    2. 某服务器上线时会自动将服务器的信息注册到注册中心,下线时会自动更新服务器的状态;
    1. 主节点选举,服务器上下线,分片总数变更均更新重新分片标记;
    2. 定时任务触发时,如需重新分片,则通过主服务器分片,分片过程中阻塞,分片结束后才可以执行任务。如分片过程中主服务器下线,则先选举主服务器在分片;
    3. 由上一项说明可知,为了维持作业运行时的稳定性,运行过程中只会标记分片的状态,不会重新分片,分片仅可能发生在下次任务触发前;
    4. 每次分片都会按照ip排序,保证分片结果不会产生较大的波动;
    5. 实现失效转移功能,在某台服务器执行完毕后主动抓取未分配的分片,并且在某台服务器下线后主动寻找可用的服务器执行任务。

    elastic底层的任务调度还是使用的quartz,通过zookeeper来动态给job节点分片。如果很大体量的用户需要我们在特定的时间段内计算完成,那么我们肯定是希望我们的任务可以通过集群达到水平的扩展,集群里的每个节点都处理部分的用户,不管用户的数量有多大,我们只需要增加机器就可以了。举个例子:比如我们希望3台机器跑job,我么将我们的任务分成3片,框架通过zk的协调,最终会让3台机器分配到0,1,2的任务片,比如server0->0、server1->1、server2->2,当server0执行时,可以只查询id%3==0的用户,server1可以只查询id%3==1的用户,server2可以只查询id%3==2的用户。

    在以上的基础上再增加一个server3,此时,server3分不到任何的分片,没有分到任务分片的程序将不执行。如果此时server2挂了,那么server2被分到的任务分片将会分配给server3,所以server3就会代替server2执行。如果此时server3也挂了,那么框架也会自动的将server3的任务分片随机分配到server0或者server1,那么就可能成:server0->0、server1->1,2。

    这种特性称之为弹性扩容

    2.2.2、Elastic-job-cloud

    Elastic-job-cloud包含了Elastic-job-lite的全部功能,它是以私有云平台的方式提供集资源、调度以及分片为一体的全量级解决方案,依赖于Mesos和Zookeeper,它额外提供了资源治理、应用分发以及进程隔离等服务。他们两个提供同一套API开发作业,开发者仅需一次开发,然后可根据需要以lite或cloud的方式部署。

    2.3、saturn

    Saturn(定时任务调度系统)是唯品会自主研发的分布式的定时任务的调度平台,它是基于Elastic-job版本1开发的。目标是取代传统的Linux Cron/Spring Batch Job/Quartz的方式,做到全域统一配置、统一监控、任务高可用以及分片。Saturn的任务可以使用多种语言开发,比如python、Go、Shell、Java、Php等。

             Saturn包括两大部分,Saturn Console和Saturn Executor。Console是一个WEB UI,用来对作业/Executor的管理,统计报表展现等。他同时也是整个调度系统的大脑:将作业任务分配到各Executor。Executor是执行任务的worker:按照作业配置的要求去执行部署于Executor所在容器或物理机当中的作业脚本和代码。Saturn高度依赖于zookeeper,每个executor及调度服务都会在zookeeper上进行注册,确保调度程序能够及时得到executor的状态。

    Saturn定时任务调度的最小单位是分片,即任务的一个执行单元。Saturn的基本任务就是将任务分成多个分片,并将每个分片通过算法调度到对应的executor上去执行。

    2.3.1、Staurn基本原理

    Saturn的基本原理是将作业在逻辑上划分为若干个分片,通过作业分片调度器将作业分片指派给特定的执行节点。执行节点通过quartz触发执行作业的具体实现,在执行的时候,会将分片序号和参数作为参数传入。作业的实现逻辑需分析分片序号和分片参数,并以此为依据来调用具体的实现(比如一个批量处理数据库的作业,可以划分0号分片处理1-10号数据库,1号分片可以处理11-20号数据库)。

    2.3.2、Saturn作业调度算法

    (1)方案的设计

    原理是给每个作业分片一个负载值和优先执行节点(prefer list),当需要重新分片时,参考作业优先设定和执行节点的负载值来进行域内节点之间的资源分配,从而达到资源平衡。

    (2)前置条件

    A:每个分片都引入一个负载值(load),由用户通过Saturn UI界面输入

    B:为每一个作业引入新的属性prefer list(优先列表,或者叫欲分配列表),由管理员通过ui界面编辑

    C:作业引入启用状态(enabled/disabled),用户通过UI界面改变这个状态;启用状态的作业会被节点执行,且不可编辑、删除,不可对prefer list进行调整,禁用状态的作业不会被执行

    (3)实施步骤

    第一步,摘取;第二步,放回(将这些作业分片按照负载值从大到小顺序逐个分配给负载最小的执行节点)。

    3.1executor上线

    摘取:

    第一步,找出新上线节点的全部可执行作业列表;对于每个作业,判断prefer list中是否包含了新上线的节点;如果是,则摘取其中全部的分片;这些已经处理过的作业称为预处理作业;

    第二步,从新上线节点的作业列表中减去预分配作业,然后使用以下的方法依次摘取:

    1. 假如上线的executor为a,它能处理的作业类型为j1,j2(已减去预分配列表)。遍历当前域下的executor列表,拿掉全部作业类型为j1,j2的分片,加上尚未分配的j1,j2作业分片列表,作为算法的待分配列表
    2. 在处理每个节点时,每拿掉一个作业分片后判断被拿掉的负载(load)是否已经超过了自身处理前总负载(load)的1/n(n为当前executor节点的总数量),如果超过,则本执行节点摘取完成,继续处理下一个执行节点;如果不超过则继续摘取,直到超过(大于等于)为止。

    放回:

    a.构造需要添加的作业分片列表,我们起名为待分配列表,长度为n,待分配列表按照负载(load)从大到小排序,排序时需保证相同作业的所有分片时连续的

    b.构造每种作业类型的executor列表(如果有prefer list,且有存活,则该作业的executor列表就是prefer list),得到一个map<jobName,executorList>’

    c.从待分配列表中依次取出第0到第n-1个作业分片jobi

    d.从map中取出可运行jobi的executor列表listi

    e.将jobi分配给listi中负载总和最小的executor

    举例如下:

    (3.2executor下线

    摘取:取出下线的executor当前分配到的全部作业分片,作为算法的待分配列表

    放回:使用平衡算法逐个处理待分配列表中的作业分片

    3.3)作业启动

    摘取:从所有executor中摘取将被启动作业的全部分片作为算法的待分配列表

    放回:使用调整后的平衡算法放回

    3.4)作业停止

    摘取:将被停止的作业分片从各节点删除

    返回:

     

    注:Saturn架构文档请见https://github.com/vipshop/Saturn/wiki/Saturn架构文档

    2.4、lts

    LTS是一个轻量级分布式任务调度框架,主要用于解决分布式任务的调度问题,支持实时任务、定时任务和Cron任务,有较好的伸缩性、扩展性以及健壮稳定性。他参考hadoop的思想,主要有以下四个节点:

    1. JobClient:主要负责提交任务,并接收任务执行的反馈结果
    2. JobTracker:负责接收并分配任务,任务调度
    3. TaskTracker:负责执行任务,执行完反馈给JobTracker
    4. LTS-Admin:(管理后台)主要负责节点管理,任务队列管理,监控管理等

    其中JobClient、JobTracker、TaskTracker是无状态的,可以部署多个并动态的进行删减,来实现负载均衡,实现更大的负载量,并且框架采用FailStore策略使得LTS具有很好的容错能力。

    一个典型的定时任务,大概的执行流程如下:

    1. 添加任务以后在注册中心进行注册,zk集群会暴露各个节点的信息,进行master节点选举等
    2. JobClient将任务进行提交,如果成功的话将进行下一步;否则的话进入FailStore,重试
    3. JobTracker接收并分配任务,如果任务已经存在,则结束;否则任务进入可执行队列ExecutableJobQueue,接着进入执行中任务队列ExecutingJobQueue,最后发送给TaskTracker进行执行
    4. TaskTracker执行完毕后,将结果反馈给客户端;如果反馈成功,则回到JobClient执行下一个任务;否则的话进入FeedbackJobQueue重试

    2.5、quartz

    Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于java实现。作为一个优秀的开源框架,Quartz具有以下特点:强大的调度功能、灵活的应用方式、分布式和集群能力,另外作为spring默认的调度框架,很容易实现与Spring集成,实现灵活可配置的调度功能。

    Quartz的核心元素如下:

    1. Scheduler:任务调度器,是实际执行任务调度的控制器
    2. Trigger;触发器,用于定义任务调度的时间规则
    3. Calendar:它是一些日历特定时间的集合,一个Trigger可以包含多个Calendar,以便于排除或包含某些时间点
    4. JobDetail:用来描述Job实现类及其他相关的静态信息,如Job的名字、关联监听器等信息
    5. Job:是一个接口,只有一个方法void execute(JobExecutionContext context),开发者实现该接口定义运行任务,JobExecutionContext类提供了调度上下文的各种信息

       Quartz的单机版大家应该都比较熟悉,它的集群方案是使用数据库来实现的。集群架构如下:

              上图3个节点在数据库中都有同一份Job定义,如果某一个节点失效,那么Job会在其他节点上执行。因为每个节点上的代码都是一样的,那么如何保证只有一台机器上触发呢?答案是使用了数据库锁。在quartz集群解决方案了有张scheduler_locks,采用了悲观锁的方式对triggers表进行了行加锁,以保证任务同步的正确性。

    简单来说,quartz的分布式调度策略是以数据库为边界的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性,同时多个节点的异步运行保证了服务的可靠。但这种策略有自己的局限性:集群特性对于高CPU使用率的任务效果特别好,但是对于大量的短任务,各个节点都会抢占数据库锁,这样就出现大量的线程等待资源。Quartz的分布式只解决了任务高可用的问题,并没有解决任务分片的问题,还是会有单机处理的极限。

    2.6、TBSchedule

    TBSchedule是一款非常优秀的分布式调度框架,广泛应用于阿里巴巴、淘宝、支付宝、京东、汽车之家等很多互联网企业的流程调度系统。TBSchedule在时间调度方面虽然没有quartz强大,但是它支持分片的功能。和quartz不同的是,TBSchedule使用zk来实现任务调度的高可用和分片。纯java开发。

    TBSchedule项目实际上可以分为两部分。1)schedule管理控制台。负责控制、监控任务执行状态。2)实际执行job的客户端程序。在实际使用时,需要先启动zk,然后部署TBSchedule web界面的管理控制台,最后启动实际执行job的客户端程序。这里的zk并不实际控制任务调度,它只是负责与N台执行job任务的客户端进行通讯,协调、管理、监控这些机器的运行信息。实际分配任务的是管理控制台,控制台从zk获取job的运行信息。TBSchedule通过控制ZNode的创建、修改、删除来间接控制job的执行,执行任务的客户端监听它们对应ZNode的状态更新事件,从而达到TBSchedule控制job执行的目的。特点:

    1. TBSchedule的分布式机制是通过灵活的Sharding方式实现的,比如可以按所有数据的ID按10取模分片、按月份分片等,根据不同的场景由客户端配置分片规则。
    2. TBSchedule的宿主服务器可以进行动态的扩容和资源回收,这个特点主要是因为它后端依赖的zooKeeper,这里的zooKeeper对于TBSchedule来说相当于NoSQL,用于存储策略、任务、心跳等信息数据,他的数据结构类似于文件系统的目录结构,他的节点有临时节点、持久节点之分。一个新的服务器上线后,会在zk中创建一个代表当前服务器的一个唯一性路径(临时节点),并且新上线的服务器会和zk保持长连接,当通信断开后,节点会自动删除。
    3. TBSchedule会定时扫描当前服务器的数量,重新进行任务分配。
    4. TBSchedule不仅提供了服务端的高性能调度服务,还提供了一个scheduleConsole war随着宿主应用的部署直接部署到服务器,可以通过web的方式对调度的任务、策略进行监控管理,以及实时更新调整。

    2.7、xxl-job

    xxl-job是一个轻量级的分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。

    xxl-job的设计思想为:

       (1)将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求

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

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

        xxl-job系统的组成分为:

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

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

    Xxl-job的执行流程:

    首先准备一个将要执行的任务,任务开启后到执行器中注册任务的信息,加载执行器的配置文件,初始化执行器的信息,然后执行器start。在admin端配置任务信息,配置执行器的信息。就可以控制任务的状态了。

    xxl-job的特性为:

    1. 简单:支持通过web页面对任务进行CRUD操作,操作简单
    2. 动态:支持动态修改任务状态、暂停/恢复任务,以及终止运行中的任务,即时生效
    3. 调度中心HA(中心式):调度采用中心式设计,“调度中心”基于集群Quartz实现并支持集群部署,可保证调度中心HA
    4. 执行器HA:任务分布式执行,任务执行器支持集群部署,可保证任务执行HA
    5. 注册中心:执行器会周期性自动注册任务并触发执行。同时,也支持手动录入执行器地址
    6. 弹性扩容缩容:一旦有新的执行器机器上线或下线,下次调度时会重新分配任务
    7. 路由策略:执行器集群部署时提供丰富的路由策略,包括:第一个、最后一个、轮询、随机、最不经常使用、故障转移等
    8. 故障转移:任务路由策略选择"故障转移"情况下,如果执行器集群中某一台机器故障,将会自动Failover切换到一台正常的执行器发送调度请求。
    9. 阻塞处理策略:调度过于密集执行器来不及处理时的处理策略,策略包括:单机串行、丢弃后续调度、覆盖之前调度
    10. 任务超时控制:支持自定义任务超时时间,任务运行超时将会主动中断任务;
    11. 任务失败重试:支持自定义任务失败重试次数,当任务失败时将会按照预设的失败重试次数主动进行重试;
    12. 失败处理策略;调度失败时的处理策略,默认提供失败告警、失败重试等策略;
    13. 分片广播任务:执行器集群部署时,任务路由策略选择"分片广播"情况下,一次任务调度将会广播触发集群中所有执行器执行一次任务,可根据分片参数开发分片任务;
    14. 动态分片:分片广播任务以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
    15. 事件触发:除了"Cron方式"和"任务依赖方式"触发任务执行之外,支持基于事件的触发任务方式。调度中心提供触发任务单次执行的API服务,可根据业务事件灵活触发。
    16. 任务进度监控:支持实时监控任务进度;
    17. Rolling实时日志:支持在线查看调度结果,并且支持以Rolling方式实时查看执行器输出的完整的执行日志;
    18. GLUE:提供Web IDE,支持在线开发任务逻辑代码,动态发布,实时编译生效,省略部署上线的过程。支持30个版本的历史版本回溯。
    19. 脚本任务:支持以GLUE模式开发和运行脚本任务,包括Shell、Python、NodeJS等类型脚本;
    20. 任务依赖:支持配置子任务依赖,当父任务执行结束且执行成功后将会主动触发一次子任务的执行, 多个子任务用逗号分隔;
    21. 一致性:“调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行;
    22. 自定义任务参数:支持在线配置调度任务入参,即时生效;
    23. 调度线程池:调度系统多线程触发调度运行,确保调度精确执行,不被堵塞;
    24. 数据加密:调度中心和执行器之间的通讯进行数据加密,提升调度信息安全性;
    25. 邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件;
    26. 推送maven中央仓库: 将会把最新稳定版推送到maven中央仓库, 方便用户接入和使用;
    27. 运行报表:支持实时查看运行数据,如任务数量、调度次数、执行器数量等;以及调度报表,如调度日期分布图,调度成功分布图等;
    28. 全异步:系统底层实现全部异步化,针对密集调度进行流量削峰,理论上支持任意时长任务的运行;
    29. 国际化:调度中心支持国际化设置,提供中文、英文两种可选语言,默认为中文;

     

    xxl-job-lite的执行器实际是一个ConcurrentHashMap容器。

     

    3、任务调度框架的技术选型?

    1、Quartz:Java事实上的定时任务标准,但是关注点在于定时任务而非数据,虽然实现了高可用,但是缺少分布式并行调度的功能,性能低。

    2、TBSchedule:阿里早期开源的分布式任务调度系统。代码略陈旧,使用的是Timer而不是线程池执行任务调度。TBSchedule的作业类型比较单一,只能是获取/处理数据一种模式,文档缺失比较严重。

    3、详见分布式调度框架对比表格~

    4、分布式任务调度框架的安装与使用?

    4.1、Elastic-job

    1、环境准备:

    jdk1.7+、zookeeper3.4.6+、maven3.0.4+

    2、安装zookeeper3.4.12并启动

    这里zookeeper占用了2181端口。

    3、创建简单任务

    添加依赖:

    写一个简单的任务:

    在项目入口处添加作业的配置和zk的配置:

    运行,得到结果:

    4、下载Elastic-job-lite源码,使用maven进行打包。在elastic-job-lite/elastic-job-lite-console/target/elastic-job-lite-console-3.0.0.M1-SNAPSHOT/中,然后解压,会有start.bat和start.sh两个脚本,启动。

    浏览器中输入localhost:8899,就可以管理任务了。

    4.2、xxl-job-lite

    1、调度数据库初始化,tables_xxl-job.sql

    2、下载源码:包括调度中心+公共依赖+执行器示例

    3、配置部署“调度中心”:修改数据库配置——将项目进行打包——将xxl-job-admin包部署到tomcat上

    4、输入localhost:8080/xxl-job-admin即可访问调度中心

    5、配置部署执行器:xxl-job-executor-sample-springboot打成jar包直接运行,其他的打成war包部署在tomcat上。

    6、写一个任务,运行,去执行器上进行注册,然后调度中心配置执行器信息,添加任务

     

     

    附录

    1、etcd

        etcd是一个开源的、分布式的键值对数据存储系统,提供共享配置、服务的注册和发现。etcd内部采用raft协议作为一致性算法,是基于Go语言实现的。

    2、zookeeper

    zookeeper是一个开源的分布式协调服务,它为分布式应用提供了高效且可靠的分布式协调服务,提供了诸如统一命名空间服务、配置服务和分布式锁等分布式基础服务。

    3、分布式锁

        假如我们由三台机器,每台机器上都有一个进程。假设我们在第一台机器上挂载了一个资源,三个进程都要来竞争这个资源。我们不希望这三个进程同时来访问,那么就需要有一个协调器,来让他们有序的对该资源进行访问。这个协调器就是我们所说的那个锁,比如说“进程1”在使用该资源的时候,就会先去获得锁,“进程1”就对该资源保持独占,这样其他的进程就无法访问该资源。“进程1”用完该资源后就会将锁释放掉,让其他的进程来获得锁。因此这个锁机制就能保证我们的进程有序的访问该资源。就称作为“分布式锁”,是分布式协调技术实现的核心内容

    4、分片

    任务的分布式执行,需要将一个任务拆分为多个独立的任务项,然后由分布式的服务器分别执行某一个或几个分片项。

    5、单点故障

    通常分布式系统采用主从模式,就是一个主控机连接多个处理节点。主节点负责分发任务,从节点负责处理任务,当我们的主节点发生故障时,那么整个系统就瘫痪了,这就叫做单点故障。

    传统的解决办法:

    就是准备一个备用节点,这个备用节点定期给当前主节点发送ping包,主节点收到ping包后向备用节点发送回复Ack,当备用节点收到回复后就会认为主节点还活着,让他继续提供服务。

    当主节点挂了,那么备用节点就收不到Ack回复了,然后备用节点就代替它成为了主节点。

    但是存在一个安全隐患,那就是当发生网络故障时,备用节点收不到主节点的回复Ack,他会认为主节点死了,它会代替主节点成为新的主节点。

    zookeeper解决方案:

    在引入了zookeeper后我们启用了两个主节点,A和B启动后他们都会去Zookeeper去注册一个节点,假设A注册的节点为master-01,B注册的节点为master-02,注册完之后进行选举,编号最小的节点将被选举为主节点。

    如果A挂了,它在zookeeper注册的节点将会被自动删除,Zookeeper感知到节点的变化,然后再次发出选举,这时候B将获胜成为新的主节点。如果A恢复了,它会去zookeeper再注册一个节点,编号为master-03。这时zookeeper感知到节点的变化,会再次发起选举,此时还是B胜出。那么B继续担任主节点,A则成为备用节点。

    6、Mesos

        ——像用一台电脑一样使用整个数据中心

    是Apache下的开源分布式资源管理框架,它被称为分布式系统的内核,是以与Linux内核同样的原则而创建的,不同点仅仅是在于抽象的层面。使用ZooKeeper实现Master和Slave的容错。

    7、FailStore策略

        FailStrore,顾名思义就是Fail and Store,这个主要是用于失败了存储的,主要用于节点容错,当远程数据交互失败后,存储在本地,等待远程通讯恢复后,再将数据进行提交。

    展开全文
  • Quartz,水晶、石英,一个简单朴素有美丽的名字,在Java程序界,Quartz大名鼎鼎,很多Java应用几乎都集成或构建了一个定时任务调度系统,Quartz是一个定时任务调度框架。 何为定时任务调度框架?简而言之,它可以...

    Quartz,水晶、石英,一个简单朴素有美丽的名字,在Java程序界,Quartz大名鼎鼎,很多Java应用几乎都集成或构建了一个定时任务调度系统,Quartz是一个定时任务调度框架。

    何为定时任务调度框架?简而言之,它可以领会我们的意图在未来某个时刻做我们想要做的事情,比如,女友生日那天定时发送短信讨好下(当然,除此之外,你还要买买买…)。

    (本文章分享在CSDN平台,更多精彩请阅读 东陆之滇的csdn博客:http://blog.csdn.net/zixiao217)

    我们的应用程序有些定时任务(例如想在凌晨十二点半统计某个互联网金融公司一款借款APP前一天的借款、还款以及逾期情况)需要在指定时间内执行或者周期性执行某个任务(比如每月最后一天统计这个月的财务报表给财务部门等),这时候我们就需要用到任务调度框架了。Quartz正是一个炙手可热的任务调度框架,它简单易上手,并且可以与Spring集成(这才是重点)。

    现在,我们带着疑问开始认识Quartz…

    基本问题

    Quartz是什么?

    Quartz是一个任务调度框架(库),它几乎可以集成到任何应用系统中。术语”job schedule”似乎为不同的人提供了不同的想法。当你阅读该教程时,你应该能够得到一个坚定的想法关于我们使用这个术语时表达含义,但总之,作业调度是负责执行(或通知)其他软件组件在预定时间执行的服务组件。

    Quartz是非常灵活的,并包含多个使用范例,它们可以单独或一起使用,以实现您所期望的行为,并使您能够以最“自然”的方式来编写您的项目的代码。

    Quartz是非常轻量级的,只需要非常少的配置 —— 它实际上可以被跳出框架来使用,如果你的需求是一些相对基本的简单的需求的话。

    Quartz具有容错机制,并且可以在重启服务的时候持久化(”记忆”)你的定时任务,你的任务也不会丢失。

    虽然通过schedule可以简单实现一些系统任务定时执行,当您学习如何使用它来驱动应用程序的业务流程的流程时,Quartz的全部潜力是可以实现的。

    Quartz又不是什么?

    Quartz不是一个任务队列——虽然它确实可以在一些小规模应用中合理的作为一个任务队列来使用。

    Quartz不是一个网格计算引擎——虽然在某些小规模应用中,这样做确实可以达到应用的要求(定时计算、统计一些数据)。

    Quartz不是一个提供给业务人员的执行服务——它是一个库,很容易集成到应用程序中去做一些未来某时刻可能会一直循环执行的相关的任务。

    从一个软件组件角度来看Quartz是什么?

    Quartz是一个很轻量级的java库,几乎包含了所有定时的功能。主要接口是Schedule,提供了一些简单的操作:安排任务或取消任务,启动或者停止任务。

    如果你想在应用中使用Quartz,应该实现Job接口,包含了一个execute()方法。如果你想在一个任务执行时间到了的时候通知你,组件应该实现TriggerListener 或者JobListener 接口。

    Quartz任务可以在你的应用中启动和执行,可以作为一个独立的应用程序(通过RMI接口),也可是在一个J2EE应用中执行。

    为什么不简单的使用just use java.util.Timer就行了呢?

    从JDK1.3开始,Java通过java.util.Timerjava.util.TimerTask可以实现定时器。为什么要使用Quartz而不是使用Java中的这些标准功能呢?

    原因太多了,这里列举几个:

    • Timers没有持久化机制.
    • Timers不灵活 (只可以设置开始时间和重复间隔,不是基于时间、日期、天等(秒、分、时)的)
    • Timers 不能利用线程池,一个timer一个线程
    • Timers没有真正的管理计划

    还有什么是可以替代Quartz的?

    商业上,你还可以使用 Flux scheduler

    其他问题

    Quartz可以运行多少任务?

    这是一个很难回答的问题…答案基本上是“它取决于使用情况”
    我知道你讨厌这样的答案,所以这里的一些信息:

    首先,你使用的JobStore扮演着一个重要的因素。基于RAM的JobStore(100x)比基于JDBC的JobStore更快近乎100倍。JDBC JobStore速度几乎完全取决于您的数据库的连接速度,使用的数据库系统,以及数据库运行的硬件设备,Quartz几乎全部时间花在数据库上了。当然RAMJobStore存储多少JobTriggers也是有限制的,你使用的空间肯定比数据库的硬盘空间要小了。你可以查看“如何提升JDBC-JobStore的性能”的问题。

    因此,限制JobTriggers可以存储或监听的数量的因素是存储空间的大小(RAM的数量和磁盘空间大小)。

    关于通过RMI使用Quartz的问题

    RMI是有问题的,特别是你如果不清楚通过RMI机制时类是如何加载的话。强烈建议读读所有关于RMI的java API。强烈建议您阅读以下的参考资料:
    一个关于RMI和代码库的极好描述: http://www.kedwards.com/jini/codebase.html。很重要的一点是要意识到“代码”是由客户端使用!

    关于安全管理器的一些信息: http://gethelp.devx.com/techtips/java_pro/10MinuteSolutions/10min0500.asp.
    重要的一点:
    RMI的类装载器将不会从远程位置下载任何类如果没有设置安全管理器的话。

    关于Job的一些问题

    如何控制Job的实例?

    可以查看org.quartz.spi.JobFactoryorg.quartz.Scheduler.setJobFactory(..) 的方法。

    当一个Job完成并移除之后,还能保存吗?

    设置属性:JobDetail.setDurability(true)——当job不再有trigger引用它的时候,Quartz也不要删除job。

    如何保证一个job并发执行?

    实现StatefulJob 而不是Job,查看更多关于StatefulJob 的信息。

    如何停止一个正在执行的Job?

    查看org.quartz.InterruptableJob接口和Scheduler.interrupt(String, String)方法。

    关于Trigger的一些问题

    怎么执行任务链?或者说怎么创建工作流?

    目前还没有直接的或自由的方式通过Quartz链式触发任务。然而,有几种方法,你可以轻易的达到目标。

    方法一:
    使用监听器(TriggerListener,JobListener 或者SchedulerListener),可以通知到某个工作完成,然后可以开始另一个任务。这种方式有一点复杂,你必须告知监听器哪个任务是接着哪个任务的,你可能还会担心这些信息的持久性。可以查看org.quartz.listeners.JobChainingJobListener,已经具有一些这样的功能了。
    方法二:
    创建一个Job,它的JobDataMap 包含下一个Job的名字,当这一个job执行完毕再执行下一个任务。大多数的做法是创建一个基类(通常是抽象类或接口)作为Job,并拥有获得job名称的方法,使用预定义的key从JobDataMap 进行分组。抽象类实现execute()方法委托模板方法例如”doWork()”去执行,它包含了调度后续作业的代码。之后子类要做的只是简单的扩展这个类,包括做自己应该做的工作。持久化job的使用,或者重载addJob(JobDetail, boolean, boolean) 方法(Qartz2.2新增的)帮助应用程序使用适当的数据来定义所有的工作,并没有创建触发器来激发他们(除了一个触发器触发外链中的第一个job)。
    以后,Quartz 将会提供一个更简洁的方式处理这个流程,但是现在你可以考虑前面两种处理方式或其他更好的方式处理工作流。

    为什么我的触发器trigger没有执行?

    常见的原因可能是没有调用Scheduler.start()方法,这个方法它告诉调度程序启动触发器。还有一种可能是trigger或者trigger group被暂停了。

    夏令时和触发器

    CronTrigger SimpleTrigger以自己的方式处理夏令时——每一个方式,都是直观的触发类型。

    首先,了解下什么是夏令时,可以查看:https://secure.wikimedia.org/wikipedia/en/wiki/Daylight_saving_time_around_the_world。一些读者可能没意识到,不同的国家/内容的规则是不同的。举个例子,2005年的夏令时起始于4月3日(美国)而埃及是4月29。同样重要的是要知道,不同地区不仅仅是日期不同,日期转换(前一天和后一天的中国是零点)也是不同的。许多地方移在凌晨两点,但其他地方可能是凌晨1:00,凌晨3点等。

    SimpleTrigger可以让你安排一个任务在任何毫秒级执行。可以每N毫秒执行一次任务。总是每N秒就发生一次,与一天中的时间没有关系。
    CronTrigger可以让你在某些时刻执行任务,是按”公历”时间计算的。在指定的一天中的时间触发,然后计算下一次触发的时间。

    关于JDBCJobStore的一些问题

    怎么提升JDBC-JobStore的性能?

    下面有一些提升JDBC-JobStore性能的方法,其中只有一种是有效的:

    • 使用更快更好的网络
    • 买一个更好的机器
    • 买一个更好的RDBMS

    现在,提供一种简单的但有效的方式:在Quartz表建立索引。

    很多数据库系统都会自动把索引放在主键字段上,许多数据库系统也会对外键也建立索引。确保你的数据库是这样做的,或者手动为表的关键字建立索引。
    最重要的索引的TRIGGER 表的next_fire_timestate字段。最后但不是重要的,为FIRED_TRIGGERS 表的每一个字段设置索引。

    create index idx_qrtz_t_next_fire_time on qrtz_triggers(NEXT_FIRE_TIME);
    create index idx_qrtz_t_state on qrtz_triggers(TRIGGER_STATE);
    create index idx_qrtz_t_nf_st on qrtz_triggers(TRIGGER_STATE,NEXT_FIRE_TIME);
    create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
    create index idx_qrtz_ft_trig_group on qrtz_fired_triggers(TRIGGER_GROUP);
    create index idx_qrtz_ft_trig_name on qrtz_fired_triggers(TRIGGER_NAME);
    create index idx_qrtz_ft_trig_n_g on \
        qrtz_fired_triggers(TRIGGER_NAME,TRIGGER_GROUP);
    create index idx_qrtz_ft_trig_inst_name on qrtz_fired_triggers(INSTANCE_NAME);
    create index idx_qrtz_ft_job_name on qrtz_fired_triggers(JOB_NAME);
    create index idx_qrtz_ft_job_group on qrtz_fired_triggers(JOB_GROUP);
    create index idx_qrtz_t_next_fire_time_misfire on \
        qrtz_triggers(MISFIRE_INSTR,NEXT_FIRE_TIME);
    create index idx_qrtz_t_nf_st_misfire on \
        qrtz_triggers(MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
    create index idx_qrtz_t_nf_st_misfire_grp on \
        qrtz_triggers(MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

    集群功能最适合于长时间运行和/或密集的工作(在多个节点上分配工作负载),如果你需要扩展到支持成千上万的短运行(例如1秒)的工作,考虑工作集分割使用多个不同的调度器(因此多套表(有不同的前缀))。当你添加多个客户端的时候,使用一个调度程序将会强制使用一个集群锁,一个模式,降低性能。

    如果数据库服务器重新启动,我的数据库连接不会恢复正常

    如果您正在创建连接数据源(通过指定在Quartz属性文件中的连接参数),请确保您有一个指定的连接验证查询:

    org.quartz.dataSource.myDS.validationQuery=select 0 from dual

    这个专门的查询语句对Orable数据库是非常有效的。其他的数据库,可以使用合适的sql。

    如果你的数据源是由您的应用程序服务器管理,确保数据源配置在这样一种方式,它可以检测连接失败。

    关于Transactions事务的一些问题

    使用JobStoreCMT,并且遇到死锁,该怎么办?

    JobStoreCMT 在大量使用,滥用可以导致死锁。不管怎样,我们总是抱怨死锁。到目前为止,该问题已被证明是“用户错误”。如果遇到死锁,下面的列表可能是你需要检查的事情了:

    • 当一个事务执行很长时间时,有些数据库会把它当成死锁。 确保你已经设置了索引 。
    • 确保在你的线程池中至少有两个以上数据库连接。
    • 确保你有一个托管的和非托管的数据源供Quartz使用。
    • 确保你在一个任务中处理的业务是在一个事务中。 处理完记得提交事务。
    • 如果你的 Jobs的 execute()方法 使用schedule, 确保使用UserTransaction或者设置Quartz属性:"org.quartz.scheduler.wrapJobExecutionInUserTransaction=true".

    集群、规模化和高可用特性

    Quartz有什么集群能力?

    Quartz具有可扩展和高可用性功能。你可以在Quartz配置资料中找到答案:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/

    其他的集群配置,不依赖后台数据库,Terracotta

    展开全文
  • 主要为大家详细介绍了Quartz.Net调度框架的配置方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • earth-frost是一个轻量级分布式任务调度框架。 介绍: 调度模块和执行模块分离 使用redis作为数据库 基于订阅模式实现服务注册和发现 环境: Angular: v1.x JDK: 1.8+ Maven: 3+ Redis: 2.8+ Spring boot: 2.x ...
  • 浅谈分布式任务调度框架

    千次阅读 2020-06-27 22:56:34
    接下来我们首先分析分布式任务调度框架相对单机的优势以及结合几种任务调度框架分析是如何逐步实现分布式的高可用、效率的,最后综合比较下业界比较流行的框架,在项目开发中方便选择。 2、Why 分布式任务调度框架 ...

    1、前言

    上一篇文章谈了单机的定时任务解决方案,只能在单个JVM进程中使用;而我们的现在基本上是分布式场景,需要一套在分布式环境下高性能、高可用、可扩展的分布式任务调度框架;是否将之前的单机解决方案部署到分布式就可以?面临的分布式场景如何实现分布式的任务调度,如何解决单点故障问题实现高可用?接下来我们首先分析分布式任务调度框架相对单机的优势以及结合几种任务调度框架分析是如何逐步实现分布式的高可用、效率的,最后综合比较下业界比较流行的框架,在项目开发中方便选择。

    2、Why 分布式任务调度框架

    背景

    1、单点故障

    举个例子,村里只有一口井,有口井突然被污染了,村里就都没有井水喝了;分布式就是平时挖了多口井,一口井出问题照样有水喝。
    image.png

    image.png

    之前我们说到单机的定时任务可能机器存在异常,如果没有分布式任务调度,那这个机器上所有定时任务只能等到这个机器恢复后才可以执行,这显然可用性就很低。

    分布式任务调度就是在集群中多台调度、多台执行,一台调度机器或者执行机器出问题,能够立刻故障转移,不影响后续任务的执行,提高整体的可用性。

    2、性能瓶颈

    都知道一台机器的CPU、内存资源是有限的,像我们单机任务都直接写在业务机器上,单机任务瓶颈立现;当定时任务多,每秒执行上W个定时任务,单机是难以支撑的,而且定时任务会影响到业务系统的资源,整个系统就会非常不可靠。单机靠多线程,单机瓶颈达到后就要依靠分布式集群来水平扩展,解决资源瓶颈问题。

    3、协同效率

    每个定时任务调度的使用业务方都需要自己在业务系统构造一套分布式定时任务调度框架吗?这显然是低效?专业分工是必然的发展趋势,这就需要分布式的任务调度框架的出现,其他业务作为接入方,使用即可,不需要再考虑分布式调度的调度策略的高可用、异常故障恢复、控制台配置等等问题,只需要专注业务逻辑即可。

    3、演进过程

    什么是分布式任务调度

    分布式任务调度,三个关键词:分布式、任务调度、配置中心。
    分布式:平台是分布式部署的,各个节点之间可以无状态和无限的水平扩展(保证可扩展);

    任务调度:涉及到任务状态管理、任务调度请求的发送与接收、具体任务的分配、任务的具体执行;(集群中哪些机器什么时候执行什么任务,所以又需要一个可以感知整个集群运行状态的配置中心)

    配置中心:可以感知整个集群的状态、任务信息的注册

    常见的分布式任务调度框架一般有以下5个部分
    1、控制台:负责调度任务的配置、任务状态、信息展示
    2、接入:将控制台的任务转化下发给调度器,并且向注册中心注册任务
    3、调度器:接收接入下发的调度任务,进行任务拆分下发,在注册中心找执行器,然后把任务下发到执行器执行,同时也注册到注册中心
    4、执行器:接收调度任务,并且上报状态给注册中心
    5、注册中心:机器、任务状态的同步、协调

    现在林林总总的框架,大部分都是在Quartz的基础上进行改进,我们先来看看经典的Quartz怎么做的?

    Quartz

    Quartz是OpenSymphony开源组织在任务调度领域的一个开源项目,完全基于java实现。作为一个优秀的开源框架,Quartz具有以下特点:强大的调度功能、灵活的应用方式、分布式和集群能力,另外作为spring默认的调度框架,很容易实现与Spring集成,实现灵活可配置的调度功能。

    Quartz框架的核心对象

    Scheduler – 核心调度器,就是任务调度、分配的控制器
    Job – 任务,代表具体要执行的任务,是个接口,里面有默认方法,开发者需要实现该接口,并且业务逻辑写在默认的execute方法中
    JobDetail – 任务描述,描述job的静态消息,是调度器需要的数据,跟Job区分开来,主要是为了一个Job可以在多台机器并行,每个调度器new一个Job的实现类
    Trigger – 触发器,用于定义任务调度的时间规则

    #对象之间的关系

    这是单机Quartz最小的执行单元的关系
    image

    集群部署

    image.png

    上图3个节点在数据库中都有同一份Job定义,如果某一个节点失效,那么Job会在其他节点上执行。因为每个节点上的代码都是一样的,那么如何保证只有一台机器上触发呢?答案是使用了数据库锁。在quartz集群解决方案了有张scheduler_locks,采用了悲观锁的方式对triggers表进行了行加锁,以保证任务同步的正确性。

    简单来说,quartz的分布式调度策略是以数据库为边界的一种异步策略。各个调度器都遵守一个基于数据库锁的操作规则从而保证了操作的唯一性,同时多个节点的异步运行保证了服务的可靠。(实际上是用数据库锁作为分布式锁解决同步问题实现异步运行,跟redis、zk做分布式锁时是一样的)

    但这种策略有自己的局限性:集群特性对于高CPU使用率的任务效果特别好,但是对于大量的短任务,各个节点都会抢占数据库锁,这样就出现大量的线程等待资源。

    因此Quartz的分布式只解决了任务高可用(减少单点故障)的问题,处理能力瓶颈会在数据库,而且没有执行层面的任务分片,无法最大化效率,只能依靠shedulex调度层面做分片,但是调度层做并行分片难以结合实际的运行资源情况做最优的分片。

    quartz通过数据库锁的方式来保证分布式环境下定时任务调度的同步,解决了单点故障,只引入了数据库,整体的结构简单;但是在效率上,由于数据库锁带来的竞争冲突,会使得在短任务较多时的低效,并且没有在执行时对任务分片,无法充分利用集群性能,也就是说没法真正的做到水平扩展,瓶颈被数据库锁限制住了。

    Elastic-job

    要解决这个分布式的水平扩展、效率问题,我们知道需要引入注册中心进行协调,这里当当退出的Elastic-job就是Quartz的基础上,引入ZK做注册中心。并且在2.0版本后出现了两个相互独立的产品线:Elastic-job-lite和Elastic-job-cloud。Elastic-job-lite定位为轻量级无中心化的解决方案,使用jar包的形式提供分布式任务的协调服务,外部依赖仅依赖于zookeeper。

    elastic-job-lite的结构

    这款轻量级的架构做了很多的改进,这里只谈到两点,
    1、无中心调度节点
    Elastic-job-lite并无作业调度中心节点,不像我们谈到单机定时任务调度有统一的排序队列,它是基于部署作业框架的程序在到达相应时间点时各自触发调度。注册中心仅用于作业注册和监控信息存储,而主作业节点仅用于处理分片和清理的功能。
    2、实现弹性扩容
    通过zookeeper来动态给job节点分片。如果很大体量的用户需要我们在特定的时间段内计算完成,那么我们肯定是希望我们的任务可以通过集群达到水平的扩展,集群里的每个节点都处理部分的用户,不管用户的数量有多大,我们只需要增加机器就可以了。
    举个例子:比如我们希望3台机器跑job,我么将我们的任务分成3片,框架通过zk的协调,最终会让3台机器分配到0,1,2的任务片,比如server0->0、server1->1、server2->2,当server0执行时,可以只查询id%30的用户,server1可以只查询id%31的用户,server2可以只查询id%3==2的用户。

    在以上的基础上再增加一个server3,此时,server3分不到任何的分片,没有分到任务分片的程序将不执行。如果此时server2挂了,那么server2被分到的任务分片将会分配给server3,所以server3就会代替server2执行。如果此时server3也挂了,那么框架也会自动的将server3的任务分片随机分配到server0或者server1,那么就可能成:server0->0、server1->1,2。

    这样就没有基于数据库的锁冲突问题,也可以实现水平扩展

    不过也是有问题的
    1、分片数是由业务代码层决定,调度执行协调时没法进一步优化,比较静态,机器扩容后其实没法直接用到扩容后的性能
    2、缺乏统一调度,每个调度任务有重复的调度开销(检测任务trigger),并且在实现复杂的dag调度时,只能把所有业务调度写在一个实现中,不够灵活。

    阿里的定时任务框架

    1、早期是:TBSchedule

    也是基于Zk做注册中心
    优点:是支持集群、分布式,灵活的任务分片,并且有动态的服务扩容和资源回收
    缺点:使用的是Timer而不是线程池执行任务调度。TBSchedule的作业类型比较单一,只能是获取/处理数据一种模式,而且目前文档偏少

    ####2、目前推出了基于Akka架构的Schedulerx2.0
    新一代定时任务,提供分布式执行、多种任务类型、统一日志等框架,用户只要依赖schedulerx-worker这个jar包,通过schedulerx2.0提供的编程模型,简单几行代码就能实现一套高可靠可运维的分布式执行引擎。在海量数据并行任务、复杂dag调度

    可扩展的执行引擎

    Worker总体架构参考Yarn的架构,分为TaskMaster, Container, Processor三层:

    image

    • TaskMaster:类似于yarn的AppMaster,支持可扩展的分布式执行框架,进行整个jobInstance的生命周期管理、container的资源管理,同时还有failover等能力。默认实现StandaloneTaskMaster(单机执行),BroadcastTaskMaster(广播执行),MapTaskMaster(并行计算、内存网格、网格计算),MapReduceTaskMaster(并行计算、内存网格、网格计算)。
    • Container:执行业务逻辑的容器框架,支持线程/进程/docker/actor等。
    • Processor:业务逻辑框架,不同的processor表示不同的任务类型。

    以MapTaskMaster为例,大概的原理如下图所示:

    image

    其借鉴了MapReduce的模式,支持Map、MapReduce模型,在海量数据分发多台机器的效率上非常方便,支持分布跑批,针对不同的跑批场景,map模型作业还提供了并行计算、内存网格、网格计算三种执行方式:

    并行计算:子任务300以下,有子任务列表。
    内存网格:子任务5W以下,无子任务列表,速度快。
    网格计算:子任务100W以下,无子任务列表。

    并行计算实例

    考拉的kSchedule

    这里再说一个考拉的分布式定时任务框架kSchedule,大体与elastic-job类似,
    kschedule的部署架构

    这里说一点,kSchedule的无侵入性做的更好,对于简单任务不需要事先Job接口,只需要把任务bean注册成容器的Service的public方法即可,然后再配置界面配置调度任务的方法和参数即可,大大的方便的简单任务的开发和配置工作;(其实就是实现了普通类的方法级别的定时任务配置,而一般的定时任务都是类继承Job类,重写execute方法)

    这点在其他框架中实现时需要写个简单任务的调度分配任务,然后把普通类的方法和入参作为动态参数传到调度分配任务,然后利用反射,进行动态执行。

    4、综合比较选型

    简单几条原则
    1、业务起步阶段:没有自主研发运维能力,选择业界使用最多最成熟的,最好是直接买,比如阿里云的Schedulerx2.0,把技术、运维都交给阿里云,只开发业务逻辑即可;或者Elastic-job-cloud版本,在私有云上部署,功能支持也比较完善,花钱都能解决
    2、业务发展阶段:数据规模和任务规模都在扩大,有一定的研发能力,可以考虑接入成熟开源框架,比如quartz或者Elastic-job-lite都是开源的,几台机器搭建起来就可以跑,出问题了开源用解答的也比较多。每秒几千个任务没问题
    3、业务成熟阶段:每秒任务扩大到几万、几十万个,而且业务个性化需要越来越多,比如各种调度策略,批处理任务的个性化支持,这时候要选择一个开源框架的基础上进行二次开发,目前quartz或者Elastic-job-lite都是不错的选择

    具体的对比表格
    各个框架对比文档—转自:分布式调度框架大集合

    5、参考文章

    分布式调度框架大集合
    详解应对平台高并发的分布式调度框架TBSchedule
    Quartz架构整理
    开源的作业调度框架Quartz
    考拉定时任务框架kSchedule
    Schedulerx2.0分布式计算原理&最佳实践

    展开全文
  • 各种调度框架介绍

    万次阅读 2017-03-01 15:25:57
    任务调度工具 Myriad Myriad Myriad把YARN和Mesos两者的优势结合起来。通过使用Myriad项目,让Mesos和YARN可以协作,你可以完成一个实时业务...高可用分布式调度框架 Mossrose [国产] Mossrose,高可用分布式
  • Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他...
  • 进程调度基本框架

    2018-06-23 16:56:32
    进程是操作系统最重要的概念之一,进程调度是操作系统内核的重要功能,本实验要求用C语言编写一个进程调度模拟程序,使用优先级或时间片轮转法实现进程调度 2)按照实验题目要求独立正确地完成实验内容(编写、调试...
  • 当前,尽管kubernetes中的默认调度程序无法确保可以调度一组Pod,但是它将调度Pod。 在某些情况下,这会浪费资源,...方法功能轻量级无资源种族调度实施基于最新的调度框架,我们设计了调度程序。 所以只有一个时间
  • 背景 ...listener ...listener 一一进行通知,这种情况,经常会出现一些任务扎堆执行的情况,譬如登录完成...4、任务的执行,可以在调度框架的线程池里面执行。 5、任务的执行,能够获取到对应的执行时间,进行监控
  • 在大数据的集群环境中,经常用到的任务调度框架有如下几个,根据公司的业务的需要选择适合自己的业务调度的框架, ... 时间调度:基于时间条件触发程序运行  依赖调度:基于其他程序的执行结果进行调度执行  ...
  • 分布式调度框架原理与技术选型

    千次阅读 2019-08-11 10:03:25
    分布式任务调度框架 1、什么是分布式任务调度? 2、常见的分布式任务调度框架有哪些? 3、分布式任务调度框架的技术选型? 4、分布式任务调度框架的安装与使用? 大对比表格:...
  • 集群调度框架的架构演进过程

    千次阅读 2017-07-21 09:39:12
    原文:The evolution of ...之前组会上,有幸与大家探讨 Firmament: Fast, Centralized Cluster Scheduling at Scale 这篇文章(OSDI 2016),文章的作者同时发表了一篇博文,讲述了集群中调度框架的演进过程,读...
  • Quartz.NET(调度框架

    千次阅读 热门讨论 2018-03-20 20:14:22
      最近一直在开发一个定时提醒并重复的功能,于是站在巨人的肩膀上,先是问了李总,李总给我提了一个对我来说很新奇的框架,Quartz.NET,调度框架。    Quartz.NET是一个任务调度的开源框架,包括触发器操作,...
  • 大数据调度框架(一)Oozie

    千次阅读 2018-08-23 14:24:35
    之前项目中的sqoop等离线数据迁移job都是利用shell脚本通过crontab进行定时执行,这样实现的话比较简单,但是随着多个job复杂度的提升,无论是协调工作还是任务监控都变...,我们选择使用oozie来对工作流进行调度监控...
  • Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz框架包含了调度器监听、作业和触发器监听。你可以配置作业和触发器监听为全局监听或者是特定于作业和触发器的监听...
  • spring quartz 时间任务调度框架 spring quartz 时间任务调度框架 spring quartz 时间任务调度框架
  • 之前我们讲过一个分布式任务调度框架PowerJob,可以通过可视化的方式来进行任务调度。但是有时候我们只是需要一个轻量级的任务调度功能,而PowerJob需要搭建调度中心未免有些重,这时...
  • java作业调度框架Quartz

    千次阅读 2017-07-31 23:10:29
    在软件开发中,很多时候需要在特定时间时间执行某些操作,比如每天的凌晨三点、每周的周日、每个月的15号,Apache Quartz就是一个开源的作业调度框架,可以让计划的程序任务一个预定义的日期和时间运行。...
  • STM32中基于时间的任务调度框架

    千次阅读 2021-01-31 11:10:44
    STM32中基于时间片的任务调度框架 1.前言:  由于单片机只能单线程的进行工作,只是单纯在while循环中跑程序,导致效率很低,所以采用任务调度可以实现伪多线程工作,任务调度顾名思义就是在不同的时间点运行不同的...
  • XXL-JOB说明文档 导航 一. XXL-JOB概述 二.... 一....1.1 XXL-JOB是什么?...官方说明:XXL-JOB是一个轻量级分布式任务调度平台,其核心...通俗来讲:XXL-JOB是一个任务调度框架,通过引入XXL-JOB相关的依赖,按照相关格式...
  • JAVA 分布式任务调度框架Mars-Job

    千次阅读 2019-03-16 04:21:26
    开源的分布式调度框架基本上分为两种: 一种为中心化调度,如xxl,将调度任务单独提炼出来,达到解耦的目的。 另一种是去中心化调度,如elastic-job。本文介绍的项目是后者类型。 使用背景 一个web项目多机部署,web...
  • BigBen - 一种通用的,多租户,基于时间的事件调度程序和cron调度框架
  • Spring-batch任务调度框架

    千次阅读 2019-04-28 09:50:04
    Spring-batch任务调度框架 目录 一,引言 3 1,什么是批处理 3 2,什么是Spring Batch 3 二,Spring Batch结构 4 1,Spring Batch体系结构 4 2,Spring Batch主要对象 5 三,Spring Batch流程介绍 5 四,...
  • 分布式任务调度框架技术调研

    千次阅读 2017-08-25 15:23:23
    研究的目的定时任务问题一直是我们组项目的主要问题来源,很多问题的最终定位是由于定时任务异常停止导致的,例如:六马的...可监控定时任务出现故障的时候可以第一时间得到通知;(监控系统) 试用分布式定时任务,解
  • java开源调度调度框架

    千次阅读 2014-01-04 23:49:32
    cron4j是一个轻量级的java任务调度工具,可以采用Unix Crontab语法来设置任务调度时间。 更多cron4j信息    Super Scheduler  Super Scheduler是一个功能强大的计划任务程序,可...
  • 导读:调度(Scheduling)在计算机领域是个庞大概念,CPU调度、内存调度、进程调度等都可称之为调度。...ElasticJob 诞生于 2015年,当时业界虽然有 QuartZ 等出类拔萃的定时任务框架,但缺乏分布式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 161,203
精华内容 64,481
关键字:

时间调度框架