这是我参与「第五届青训营 」笔记创作活动的第12天
1 概述
1.1 分布式定时任务发展历史
Windows运行批处理文件Windows任务计划程序Linux命令—CronJob应用程序编码层—单机定时任务(Timer—Java、Ticker—Go、ScheduledExecutorService—线程池技术)任务调度—Quartz(单任务极致控制、没有负载均衡机制)分布式定时任务(平台化管理、分布式部署、支持海量数据)
1.2 特点
任务调度就是设点某一时间点自动触发的任务,该任务可以在时间规律上去循环执行。一般的技术quartz、spring task、java.util.Timer,这几种如果在单一机器上跑其实问题不大,但是如果一旦应用于集群环境做分布式部署,就会带来一个致命的问题,那就是重复执行,当然解决方案有,但是必须依赖数据库,将任务执行状态持久化下来。
特点:
时间驱动:系统一般可以通过时间来驱动,定时定点定次。
批量处理:批量处理堆积的数据更加高效,在不需要实时性的情况下比消息中间件更有优势。而且有的业务逻辑只能批量处理。如对账批处理、资金管理系统回盘、部分银行的报盘前的制盘
非实时性:定时任务不要求实时性,一般不用于C端用户的交互,更多的用于业务数据的处理
隔离性/专一性:可以跟其他系统分离,只关注业务数据的处理,不影响用户的操作和用户系统的性能。
1.3 流行框架
- Quartz:Java事实上的定时任务标准。但Quartz关注点在于定时任务而非数据,并无一套根据数据处理而定制化的流程。虽然Quartz可以基于数据库实现作业的高可用,但缺少分布式并行调度的功能。
- TBSchedule:阿里早期开源的分布式任务调度系统。代码略陈旧,使用timer而非线程池执行任务调度。众所周知,timer在处理异常状况时是有缺陷的。而且TBSchedule作业类型较为单一,只能是获取/处理数据一种模式。还有就是文档缺失比较严重。
- Elastic-job:当当开发的弹性分布式任务调度系统,功能丰富强大,采用zookeeper实现分布式协调,实现任务高可用以及分片,目前是版本2.15,并且可以支持云开发,目前是版本2.15,现在已经不在更新。
- Saturn:是唯品会自主研发的分布式的定时任务的调度平台,Saturn (任务调度系统)是唯品会开源的一个分布式任务调度平台,取代传统的Linux Cron/Spring Batch Job的方式,做到全域统一配置,统一监控,任务高可用以及分片并发处理。Saturn是在当当开源的Elastic Job基础上,结合各方需求和我们的实践见解改良而成,最新发布版本V3.3.1(2019年1月18日),最新测试版本V3.3.3.1。 使用案例 唯品会、酷狗音乐、新网银行、海融易、航美在线、量富征信
- xxl-job: 是大众点评员工徐雪里于2015年发布的分布式任务调度平台,是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展,最新发布版本V2.0.2(2019.4.20日), 其在唯品会内部已经发部署350+个节点,每天任务调度4000多万次。同时,管理和统计也是它的亮点。使用案例 大众点评、易信(IM)、京东(电商系统)、360金融(金融系统)、易企秀、随行付(支付系统)、优信二手车
2 实现原理
2.1 核心架构
分布式定时任务核心要解决触发、调度、执行三个关键问题。
触发器:Trigger,解析任务,生成触发事件调度器:Scheduler,分配任务,管理任务生命周期执行器:Executor,获取执行任务单元,执行任务逻辑
2.2 控制台
任务:Job,任务元数据任务实例:JobInstance,周期任务会生成多个任务实例任务结果:JobResult,任务实例运行的结果任务历史:JobHistory,用户可以修改任务信息,任务实例对应的任务元数据可以不同,因而使用任务历史存储
2.3 触发器
给定一些列任务,解析它们的触发规则,在规定的时间点触发任务的调度,下面是一些触发器设计方案:
不同业务之间,任务的调度相互影响怎么办?负责扫描和触发的机器挂了怎么办?
存储上:不同国别、业务做资源隔离运行上:不同国别、业务分开执行部署时:采用多机房集群化部署,避免单点故障,通过数据库锁或分布式锁保证任务只被触发一次
2.4 调度器
根据调度的资源来源可以分为两种方案:
业务系统提供资源(阿里、美团、字节)
优点:任务执行逻辑与业务系统共用一份资源,利用率高缺点:更容易发生定时任务脚本影响在线业务的事故;不能由定时任务平台控制扩缩容
定时任务平台提供机器资源(字节)
优点:任务执行逻辑与业务系统提供的在线服务隔离,避免相互影响,可以优化扩缩容缺点:消耗更多机器资源;需要额外为定时任务平台申请接口调用权限,而不能直接继承业务系统的权限
资源调度—节点选择:
随机节点执行:选择集群中的一个可用的执行节点执行调度任务。适用场景:定时对账广播执行:在集群中所有的执行节点分发调度任务并执行。适用场景:批量运维分片执行:按照用户自定义的分片逻辑进行拆分,分发到集群中不同节点并执行,提升资源利用效率。适用场景:海量日志统计
故障转移:分片任务基于一致性Hash策略分发任务,当某个执行器异常时,调度器会将任务分发到其他执行器。高可用:调度器可以集群部署,做到完全无状态,靠消息队列的重试机制保障任务一定会被调度。
2.5 执行器
基于注册中心,可以做到执行器的弹性扩缩容。