浅谈分布式任务注册及调度的实现方法

2021-04-03 12:12俞珍秒汪明贵
中国设备工程 2021年8期
关键词:池中任务调度线程

俞珍秒,汪明贵

(南京南瑞信息通信科技有限公司,江苏 南京 210003)

随着现代信息技术的高速发展,企业的信息系统也充斥着大量的数据。为了合理地管理并利用这些数据,企业不得不对业务核心系统进行扩展,延伸出众多业务子系统。而这些子系统为了满足业务需求,又不得不严重依赖系统的核心数据。为了能有效地降低数据间的耦合,保证系统数据的一致性,业务系统通常会采用分布式任务调度系统来通知子系统的计算组件及时处理。但是核心数据的往往具有高频变化特性,这给任务调度系统和业务子系统的稳定运行都提出了挑战。

本文提供了一种基于异步式编程的分布式任务注册及调度的实现方法,命名为CaesiumServer。CaesiumServer 通过异步式编程将任务注册队列中的任务分发至不同的处理单元,提高了任务注册模块的高效性。通过任务合并,避免了不必要的任务调度,保证了任务执行方的稳定运行。最后,多种任务执行策略能够合理规划资源,满足不同场景下的任务调度需求。

1 总体设计

在CaesiumServer 的设计中,任务接收模块接收到注册任务后,将任务信息中相同的任务进行合并后更新至任务池,以此保证相同的任务不会被多次重复触发。此外,任务执行模块在获取任务池任务后,会根据任务性质直接启动任务执行程序或发布任务执行信息。最后,任务执行方的执行控制器会根据任务注册时指定的策略启动任务执行程序。

2 任务注册信息

在CaesiumServer 设计中调度引擎的任务接收模块处理任务注册信息。任务注册方根据业务的需求将任务信息按照指定的格式发送到任务注册队列中,其中的任务信息主要包括:任务执行体ID、执行类、计划开始执行时间、任务类型、任务触发URL、是否可忽略、执行策略、执行计划(Cron 表达式描述)、任务执行上下文等信息。

任务的接收模块主要是通过异步式编程框架akka 来实现。akka 框架对构建高并发、高容错性的分布式应用具有良好的支持。其中的akkaactor 模型是一种将行为定义到actor,actor 间通过消息通信,消息发送异步进行,消息处理(在actor 内)同步有序进行的一种高并发、非阻塞式编程模型。在CaesiumServer 设计中任务接收模块主要定义了三种Actor,分别为:任务合并单元、更新处理单元、常规

处理单元。任务接收模块从任务注册队列获取任务信息后,会根据任务类型分别将任务信息分发至不同的Actor 进行处理。当任务类型为“可合并”型任务时,模块会根据指定时间段内的相同内容合并成一条任务后,发送至待执行任务池。当任务类型为“更新”型任务时,会判断当前待执行任务池中是否存在未被执行的相同任务,如果存在会将本次任务中的包含的信息更新至待执行任务池;如果不存在则将本次任务发送至待执行任务池。当任务类型为“常规”型任务时,则将本次任务直接发送至待执行任务池。

处理任务注册信息中如何快速、高效的处理注册任务是其难点,因为应用注册方会同时注册大批量的任务。此时通过akka 的事件驱动机制及时触发相应的逻辑尤为重要。

3 发布/执行任务

CaesiumServer的任务执行模块以定期检查的方式,根据待执行任务池中的任务信息判断当前任务是否需要被执行。当任务需要被执行时,首先会查看该任务信息中任务触发URL 是否有设定值。如果有设定值,会通过异步调用该触发URL 来启动任务执行体;如果未设定任务触发URL,就会将任务信息发送至任务执行队列。在任务触发完成后,会根据任务的执行计划更新或删除任务池中的任务。

4 启动任务

任务执行方从任务执行队列中获取“任务执行体ID”与自身一致的待执行任务信息后,将任务交由任务执行控制器进行处理。任务执行控制器主要包含一个分发线程、一个执行线程池。分发线程主要按照任务的“执行策略”控制任务执行类以不同的方式执行。“执行策略”主要包括“队列”、“并行”、“取消当前”、“忽略当前”、“延迟”等方式。执行线程池主要用来执行各任务。

当任务的执行策略为“队列”方式时:分发线程会将任务按照“执行类”为单位,为该执行类创建一个执行队列,依次将任务发送至执行线程池中执行,直到将执行队列中的任务全部执行完成。

当任务的执行策略为“并行”方式时:分发线程会直接将该任务发送至执行线程池中执行。

当任务的执行策略为“取消当前”方式时:分发线程会判断任务执行线程池中是否存在与本任务相同的“执行类”在运行,如果存在则调用当前任务的取消逻辑,待取消成功后将本次任务发送至执行线程池中执行。如果不存在,直接将该任务发送至执行线程池中执行。

当任务的执行策略为“忽略当前”方式时:分发线程会判断任务执行线程池中是否存在与本任务相同的“执行类”在运行,如果存在则舍弃当前的任务,不对本次任务做任何处理。如果不存在,直接将该任务发送至执行线程池中执行。

当任务的执行策略为“延迟”方式时:分发线程会按照“执行类”为单位记录前次任务执行时间,如果当前时间超过延迟时间时,将本次任务发送至执行线程池中执行;如果尚未达到延迟时间会创建一个定时器,在时间到达时将任务发送至执行线程池中执行。

不同执行策略的处理方式各异,实现难度也各异。其中“取消当前”型任务处理难度较大。因为所有的任务都是在任务执行线程池中运行,如何获取当前任务的引用以及如何判断任务取消成功也是一个处理难点。实施时可通过包装类对方式对“取消当前”型任务进行封装,包装类可设计成包含当前任务、前次任务等信息。包装类的执行方法中首先需要调用前次任务的取消方法,直到取消成功后再调用当前任务的执行方法。

5 结语

CaesiumServer 可保证任务调度引擎的高效性、稳定性、容错性,改变了以往任务调度引擎的过载带来的任务触发不及时、丢失等状况。能够显著加强任务执行方的处理效率,特别是根据任务特征选择不同的执行策略能够合理的优化服务器资源,改变了以往任务执行方大量任务同时执行带来的服务器压力,甚至崩溃的风险。

猜你喜欢
池中任务调度线程
基于C#线程实验探究
基于国产化环境的线程池模型研究与实现
池中景象
老伴
基于改进NSGA-Ⅱ算法的协同制造任务调度研究
基于时间负载均衡蚁群算法的云任务调度优化
浅谈linux多线程协作
云计算环境中任务调度策略
云计算中基于进化算法的任务调度策略