对任务调度框架未来方向的思考

Reading time ~1 minute

这个任务调度框架应该做成一个类库,还是做成一个平台,这是一个需要明确的问题。

如果仅仅是一个类库,那么对用调用方来说,需要做的事情会比较多,除了要基于这个类库开发自己Job之外,还要关注数据库的部署,调度器的部署;另一方面,对类库维护者来说,虽然类库看似比较易于维护,仅仅只是发布一个jar包出去而已,但是如果类库依赖方比较多,会难以控制类库的版本升级,并且需要特别注意升级的兼容性问题,实际上不是那么容易维护。

如果做成一个平台,对于调用方来说,使用起来比类库是要方便许多的,只需要关注自己Job的开发,而不再需要数据库部署,调度部署—这些工作调度平台会负责;但是对于调度平台的维护者来说,要做的事情则要比调度类库多的多,例如平台肯定是要运行在一个集群上的,那就需要一些集群管理能力;平台上运行的任务多了之后,还需要任务监视和管理能力,这样才能知道每个任务的状态是否正常,任务的一些统计指标是否正常;为了方便每个调用方的Job代码部署和更新,还需要平台支持动态代码部署,防止一个调用方的代码更新要重启整个集群。

但是,服务化仍然是正确的方向,即便是任务调度服务相对于任务调度类库要做很多额外的工作。因为对于使用方来说,一个任务调度服务使用起来要方便太多,而且长期来说,平台能力的建设是可以长期受益的,只要建设起来,后续的维护升级就不会那么困难了,接入的项目越多平摊到每个项目的技术成本会越低。

建设一个任务调度框架,有几个问题需要解决:

  • 1.模块之间隔离 可以认为一个项目的所有Job都属于一个模块,平台需要做到每个模块之间都相互隔离,防止产生模块间依赖和冲突;
  • 2.模块动态加载 如果平台中模块很多,那就需要做到少数模块的代码更新不会导致整个平台的进程都重启,这就需要一些模块动态加载技术来实现;
  • 3.平台的企业级管理问题 对于一个企业级平台来说,运行中的各种管理能力是不可或缺的,例如任务的监控和告警,任务执行情况的统计和分析,集群状态管理等等;

有几项技术或者思想对于解决这些问题或许是帮助的:

  • 1.OSGi (https://www.osgi.org/) OSGi可以说是一个模块系统,所有OSGi应用中的代码都属于一个模块,模块之间可以隔离,而且可以对模块进行动态加载。目前也有一些基于OSGi标准的框架,例如Eclipse Equinox(http://www.eclipse.org/equinox/),Apache Karaf(https://karaf.apache.org/)和Apache Felix(http://felix.apache.org/)。这些框架简化了OSGi应用的部署和管理,其中karaf的能力比较全面,可以与一些集群管理平台如Mesos,还提供Bundle管理模块Karaf Decanter。
  • 2.jigsaw (https://www.osgi.org/) jigsaw项目已经随着Java9发布了,作为Java9内置的模块系统,自然要比OSGi更顺手,但是jigsaw在模块动态加载方面不如OSGi,而且配套工具很少,没有我们需要的企业级管理能力。
  • 3.akka (https://akka.io/) akka与上面两个实际上不是平行的概念,OSGi和jigsaw都是java的模块系统,而akka是Actor模型的一个框架,用于编写消息驱动型应用。假如用akka来实现我们的的任务调度平台,那么形态上跟我们的之前设想的有些不同,我们不在需要一个中心化的数据库来保存任务信息了,或者说不需要中心化的数据库来新增待调度的任务了,akka的封装性很高,一切消息序列化,反序列化,网络传输,actor状态持久化等待都被封装了起来,对于基于akka应用来说,只需要关注怎么把自己的应用抽象成Actor模型,也就是说怎么抽象出每个Actor,怎么制定Actor之间的消息传递逻辑。 我们的任务调度平台初步来看也是可以在不改变现有接口的情况下用akka的Actor模型来实现的。但是akka的封装的特别厚重,对于企业管理来说不见得是好事。而且akka应该是没有代码动态加载机制的,需要找其他方案实现。
  • 4.docker (https://www.docker.com/) Docker的Containner的动态启停和隔离性对任务调度平台来说是很有帮助的,但是隔离性高会给模块与平台的集成带来困难。

Post with a Background Image

Published on October 26, 2013

Syntax Highlighting Post

Published on August 16, 2013