关于github:主流定时任务解决方案全横评

2次阅读

共计 6714 个字符,预计需要花费 17 分钟才能阅读完成。

定时工作作为一种依照约定工夫执行预期逻辑的通用模式,在企业级开发中承载着丰盛的业务场景,诸如后盾定时同步数据生成报表,定时清理磁盘日志文件,定时扫描超时订单进行弥补回调等。程序开发人员在定时工作畛域有着诸多框架和计划可供选择,并借此疾速实现业务性能实现产品上线。本文将就以后支流定时工作解决方案进行介绍和剖析,冀望能够在企业技术选型和我的项目架构重构时作为参考。

Crontab

指标定位

Crontab 作为 Linux 内置的可执行命令,能够实现依照 cron 表达式生成的工夫执行指定的零碎指令或 shell 脚本。

应用形式

crontab 命令语法:

crontab [-u username] [-l | -e | -r]
参数:-u : 只有 root 用户能力进行这个工作,编辑某个用户的 crontab
-e : 编辑 crontab 的工作内容
-l : 查阅 crontab 的工作内容
-r : 移除所有的 crontab 的工作内容

配置文件示例:

* * * * * touch ~/crontab_test
* 3 * * * ~/backup
0 */2 * * * /sbin/service httpd restart

实现原理

crond 守护过程是通过 Linux 启动时的 init 过程启动,由 cornd 每分钟会查看 /etc/crontab 配置文件中是否有须要执行的工作,并通过 /var/log/cron 文件输入定时工作的执行状况。用户能够应用 Crontab 命令治理 /etc/crontab 配置文件。

计划剖析

借助 Crontab 用户能够非常便当的疾速实现繁难的定时工作性能,但存在以下痛点:

  • 定时工作与指定 linux 机器绑定,当机器扩容或者更换时须要重新配置 contab,同时存在单点故障危险
  • 随着定时工作规模增多,无对立视角对其进行工作进度的追踪和管控,难以保护
  • 性能过于简略,没有超时,重试,阻塞等工作高级个性
  • 可观测能力差,问题排查定位艰难
  • 工作常驻,当无工作执行时造成不必要的资源老本节约

Spring Task

指标定位

Spring 框架提供了开箱即用的定时调度性能,用户能够通过 xml 或者 @Scheduled 注解的形式标识指定办法执行的周期。Spring Task 反对多种工作执行模式,包含带时区配置的 corn,固定提早,固定速率等。

应用形式

代码实例如下:

@EnableScheduling
@SpringBootApplication
public class App {public static void main(String[] args) {SpringApplication.run(App.class, args);
    }
}

@Component
public class MyTask {@Scheduled(cron = "0 0 1 * * *")
    public void test() {System.out.println("test");  
    }  
      
}

实现原理

Spring Task 的原理是在初始化 bean 时借助 ScheduledAnnotationBeanPostProcessor 拦挡 @Scheduled 注解所标识的办法,并依据每个办法及其注解配置构建相应的 Task 实例注册到 ScheduledTaskRegistrar 中,并在单例 bean 初始化实现后通过 afterSingletonsInstantiated 回调设置 ScheduledTaskRegistrar 中的调度器 TaskScheduler,其底层依赖于 jdk 并发包中的 ScheduledThreadPoolExecutor 实现,并在 afterPropertiesSet 时将所有 Task 增加到 TaskScheduler 中调度执行。

计划剖析

借助 Spring Task 用户能够通过注解疾速实现对指定办法的周期性执行,反对多种周期性策略。但与 crontab 类似,同样有如下的痛点:

  • 默认为单线程执行,若前一个工作执行工夫较长会导致后续任饥饿阻塞,须要用户自行配置线程池
  • 各个节点独立运行,存在单点危险,无分布式协调机制,要思考禁止并发执行
  • 随着定时工作规模增多,无对立视角对其进行工作进度的追踪和管控,难以保护
  • 性能过于简略,没有超时,重试,阻塞等工作高级个性
  • 可观测能力差,问题排查定位艰难
  • 工作常驻,当无工作执行时造成不必要的资源老本节约

ElasticJob

指标定位

ElasticJob 作为当当网开源的一款分布式工作框架,提供弹性调度,资源管控,作业治理等诸多个性,其曾经成为 Apache Shardingsphere 的子项目。ElasticJob 目前由 2 个互相独立的子项目 ElasticJob-Lite 和 ElasticJob-Cloud 组成,ElasticJob-Lite 定位为轻量级无中心化解决方案,应用 jar 的模式提供分布式工作的协调服务;ElasticJob-Cloud 应用 Mesos 的解决方案,额定提供资源治理、利用散发以及过程隔离等服务。个别应用 ElasticJob-Lite 即可满足需要。

应用形式

使用者须要在 yaml 中配置注册核心 zk 的地址以及工作的配置信息

elasticjob:
  regCenter:
    serverLists: localhost:6181
    namespace: elasticjob-lite-springboot
  jobs:
    simpleJob:
      elasticJobClass: org.apache.shardingsphere.elasticjob.lite.example.job.SpringBootSimpleJob
      cron: 0/5 * * * * ?
      timeZone: GMT+08:00
      shardingTotalCount: 3
      shardingItemParameters: 0=Beijing,1=Shanghai,2=Guangzhou    

实现对应的接口即可标识对应的工作,同时通过配置监听器来实现工作执行前后回调:

public class MyElasticJob implements SimpleJob {
    
    @Override
    public void execute(ShardingContext context) {switch (context.getShardingItem()) {
            case 0: 
                // do something by sharding item 0
                break;
            case 1: 
                // do something by sharding item 1
                break;
            case 2: 
                // do something by sharding item 2
                break;
            // case n: ...
        }
    }
}


public class MyJobListener implements ElasticJobListener {
    
    @Override
    public void beforeJobExecuted(ShardingContexts shardingContexts) {// do something ...}
    
    @Override
    public void afterJobExecuted(ShardingContexts shardingContexts) {// do something ...}
    
    @Override
    public String getType() {return "simpleJobListener";}
}

实现原理

ElasticJob 底层工夫调度基于 Quartz,Quartz 须要长久化业务 Bean 到底层数据表中,零碎侵入性相当严重,同时通过 db 锁进行工作抢占,不反对并行调度,不具备可扩展性。而 ElasticJob 通过数据分片以及自定义分片参数的个性实现了程度扩大, 能够将一个工作拆分为 N 个独立的工作项,由分布式的服务器并行执行各自调配到的分片项。比方一个数据库中有 1 亿条数据,须要将这些数据读取进去并进行计算,就能够将这 1 亿条数据划分成 10 个分片,每一个分片读取其中的 1 千万条数据,而后计算后写入数据库。如果有三台机器执行,A 机器分到分片(0,1,2,9),B 机器分到分片(3,4,5),C 机器分到分片(6,7,8),这也是相比于 Quartz 最显著的劣势。
实现上 ElasticJob 应用 zookeeper 作为注册核心进行散布式调度协调以及 leader 节点的选举,通过注册核心的长期节点的变动来感知服务器的增减,每当 leader 节点选举,服务器高低线,分片总数变更时均会触发后续的从新分片,由 leader 节点在下次定时工作触发时进行具体的分片划分,再由各节点从注册核心中获取分片信息,作为工作的运行参数进行执行。

计划剖析

ElasticJob 作为分布式工作框架,解决了上述单节点工作无奈保障工作执行过程中的高可用和高并发下执行的性能的问题,并反对失败转移(failover)和错过执行的作业从新执行(misfire)等高级机制,但在应用过程中仍存在以下痛点:

  • 框架整体较重,须要依赖外置注册核心 zk,减少了至多三台服务器的应用老本和保护复杂度
  • 随着任务量的一直增多,zk 作为有状态中间件将会成为性能瓶颈
  • 可观测能力弱,须要额定引入 db 并配置事件追踪
  • 工作常驻,当无工作执行时造成不必要的资源老本节约

XXLJob

指标定位

XXLJob 作为公众点评员工开源的一款分布式工作框架,其外围设计指标是开发迅速、学习简略、轻量级、易扩大。XXLjob 具备丰盛的性能,如工作分片播送,超时管制,失败重试,阻塞策略等,并通过体验敌对的白屏化控制台对工作进行治理和保护。

应用形式

XXLjob 分为核心式调度器和分布式执行器两局部组成,在应用时须要别离启动,在调度核心启动时须要配置所依赖的 db 配置。
执行器须要配置调度核心的地址:

xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
xxl.job.accessToken=
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.address=
xxl.job.executor.ip=
xxl.job.executor.port=9999
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
xxl.job.executor.logretentiondays=30

通过 bean 模式办法模式创立工作和前后回调的应用形式如下:

@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
public void demoJobHandler() throws Exception {int shardIndex = XxlJobHelper.getShardIndex();
   int shardTotal = XxlJobHelper.getShardTotal();
   XxlJobHelper.log("分片参数:以后分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
}

public void init(){logger.info("init");
}

public void destroy(){logger.info("destory");
}

创立工作实现后,须要在管制台上配置工作的执行策略:

实现原理

XXLJob 实现上将调度零碎与工作解耦,其自研调度器负责管理调度信息,依照调度配置收回调度申请,反对可视化、简略且动静的治理调度信息,主动发现和路由,调度过期策略,重试策略,反对执行器 Failover。执行器负责接管调度申请并执行工作逻辑,并接管工作终止申请和日志申请,负责工作超时,阻塞策略等。调度器和执行器通过 restful api 进行通信,调度器自身无状态反对集群部署,晋升调度零碎容灾和可用性,通过 mysql 保护锁信息和长久化。执行器无状态反对集群部署,晋升调度零碎可用性,同时晋升工作解决能力。
XXLJob 一次残缺的任务调度通信流程:首先调度核心向执行器内嵌 Server 发送 http 调度申请,而后执行器执行对应的工作逻辑,待工作执行实现或超时后执行器发送 http 回调向调度核心返回调度后果。

计划剖析

XXLJob 在开源社区宽泛风行,凭借其简略的操作和丰盛的性能已在多家公司投入使用,能够较好的满足生产级别的需要,但上面的一些痛点须要改良:

  • 须要依赖外置 DB,减少了数据库的应用老本和保护复杂度
  • 依赖 DB 锁保障集群散布式调度的一致性, 当短时任务量一直增多将对 db 造成较大压力,成为性能瓶颈
  • 相较于无核心模式须要额定部署调度器,调度器和执行器均须要常驻同时为保障高可用均至多两台,当无工作执行时造成不必要的资源老本节约

Serverless Job

指标定位

Serverless 作为云计算的最佳实际和将来演进趋势,其全托管免运维的应用体验和按量付费的老本劣势使得其在云原生时代备受推崇。SAE(Serverless 利用引擎)Job 作为首款面向工作的 Serverless PaaS 平台,提供传统的用户体验。以后聚焦反对单机、播送、并行分片模型的工作,同时反对事件驱动、并发策略和超时重试等诸多个性,提供低成本、多规格、高弹性的资源实例来满足短时工作的执行。

应用形式

对于应用上述所有计划的存量利用,SAE(Serverless 利用引擎)Job 在兼容性能体验的同时反对零革新无感迁徙 ,无论用户应用的是 Crontab,Spring Task,还是 ElasticJob, XXLJob,均可将代码包或者镜像间接部署到 SAE(Serverless 利用引擎)Job 中,间接降级成为 Serverless 架构, 从而即刻领有 Serverless 所带来的技术上的劣势,节俭资源老本和运维老本。
对于运完即停的程序,无论是 Java, 还是 Shell, Python,Go, Php 均能够间接部署到 SAE(Serverless 利用引擎)Job 中, 从而即刻领有白屏化管控,全托管免运维的齐备体验以及开箱即用的可观测性能。

实现原理

SAE(Serverless 利用引擎)Job 底层为多租 Kubernetes,应用神龙裸金属平安容器、VK 对接 ECI 两种形式提供集群计算资源。用户在 SAE(Serverless 利用引擎)中运行的工作会映射到 Kubernetes 中相应的资源。其中多租能力是借助零碎隔离、数据隔离、服务隔离和网络隔离实现租户间的隔离。SAE(Serverless 利用引擎)Job 通过 Event Bridge 作为事件驱动源, 在反对丰盛调用形式的同时防止了 Kubernetes 内置定时器不保障准时触发以及精度时区上的问题。同时不断完善 Job 控制器的企业级个性,新增自定义分片,注入配置,差异化 GC, sidecar 被动退出,实时日志长久化,事件告诉等机制。并借助 Java 字节码加强技术接管任务调度,实现通用的 Java 指标框架的零革新 Serverless 化。应用 KubeVela 软件交付平台作为工作公布和治理的载体,以工作为核心,以开源凋谢的规范,通过申明式的形式实现整个云原生交付。SAE(Serverless 利用引擎)Job 将继续优化 etcd 以及调度器在短时工作高并发创立场景下的效率以及实例启动的极致弹性能力,联合弹性资源池保障任务调度的低提早和高可用。

计划剖析

SAE(Serverless 利用引擎)Job 解决了上述定时工作解决方案的各种痛点,用户无需关注工作的调度和集群资源,无需部署的额定的运维依赖组件,也无需自建一整套监控告警零碎,同时更重要的是无需云主机 7 *24h 常驻,在低资源利用率的环境下继续耗费闲置资源
SAE(Serverless 利用引擎)Job 相较于传统定时工作解决方案提供了三大外围价值:

  • 齐备全托管:提供了一站式全托管的治理界面,其工作生命周期治理、可观测性开箱即用,用户能够低心智累赘、零老本地学习应用 SAE(Serverless 利用引擎)。
  • 简略免运维:屏蔽了底层资源,用户只需关注其外围的业务逻辑开发,无需操心集群可用性、容量、性能等方面的问题。
  • 超高性价比:采纳按需应用、按量付费的模式,只有工作执行业务逻辑时才会拉起免费,其余工夫不收取任何费用,极大节俭了资源的老本开销。

总结

本文对支流定时工作解决方案(Crontab, Spring Task, ElasticJob, XXLJob, Serverless Job)的指标定位,应用形式,实现原理进行了论述,同时就企业亲密关注的性能体验,性能老本

更多内容关注 Serverless 微信公众号(ID:serverlessdevs),会集 Serverless 技术最全内容,定期举办 Serverless 流动、直播,用户最佳实际。

正文完
 0