XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
在介绍 xxl-job 之前先介绍一下 Quartz,Quartz 有差不多20年的历史,调度模型已经非常成熟了,而且很容易集成到 Spring 中去,用来执行业务是一个很好的选择。但是它也面临着一些问题,比如:
1、调度逻辑(Scheduler)和任务类耦合在同一个项目中,随着调度任务数量逐渐增多,同时调度任务逻辑逐渐加重,调度系统的整体性能会受到很大的影响;
2、Quartz 集群的节点之间负载结果是随机的,谁抢到了数据库锁就由谁去执行任务,这就有可能出现旱的旱死,涝的涝死的情况,发挥不了机器的性能。
3、Quartz 本身没有提供动态调度和管理界面的功能,需要自己根据API进行开发。
4、Quartz 的日志记录、数据统计、监控不是特别完善。
xxl-job 和 elastic-job 都是对 Quartz 进行了封装,对上面这些问题进行了改进,让我们用起来更简单,功能更强大。
跟老牌的 Quartz 相比,xxl-job 拥有更加丰富的功能。
总体上可以分成三类:
1、性能的提升:可以调度更多任务。
2、可靠性的提升:任务超时、失败、故障转移的处理。
3、运维更加便捷:提供操作界面、有用户权限、详细的日志、提供通知配置、自动生成报表等等。
下面是官网 xxl-job 的架构图,没有找到最新的,是一张 V2.1.0 的图,但是大差不差,右下角红框标出来的自研 RPC(xxl-rpc),在 V2.2.0 里面已经替换成了 restful 风格的 http 请求方式。
xxl-job将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求。将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中业务逻辑。因此,“调度”和“任务”两部分可以相互解耦,提高系统整体稳定性和扩展性;
xxl-job 的调度器和业务执行是独立的。调度器决定任务的调度,并且通过 http 的方式调用执行器接口执行任务。
一次完整的任务调度通讯流程由以下三个步骤构成:
调度中心向执行器发送的调度请求时使用RequestModel和ResponseModel两个对象封装调度请求参数和响应数据, 在进行通讯之前底层会将上述两个对象对象序列化,并进行数据协议以及时间戳检验,从而达到数据加密的功能;
自v1.5版本之后, 任务取消了”任务执行机器”属性, 改为通过任务注册和自动发现的方式, 动态获取远程执行器地址并执行。
AppName: 每个执行器机器集群的唯一标示, 任务注册以 “执行器” 为最小粒度进行注册; 每个任务通过其绑定的执行器可感知对应的执行器机器列表;
注册表: 见"xxl_job_registry"表, “执行器” 在进行任务注册时将会周期性维护一条注册记录,即机器地址和AppName的绑定关系; “调度中心” 从而可以动态感知每个AppName在线的机器列表;
执行器注册: 任务注册Beat周期默认30s; 执行器以一倍Beat进行执行器注册, 调度中心以一倍Beat进行动态任务发现; 注册信息的失效时间为三倍Beat;执行器注册摘除:
执行器销毁时,将会主动上报调度中心并摘除对应的执行器机器信息,提高心跳注册的实时性;
为保证系统”轻量级”并且降低学习部署成本,没有采用Zookeeper作为注册中心,采用DB方式进行任务注册发现;