APP下载

Elastic-Job分布式定时任务的研究和应用

2024-05-19丁文婷卜言彬

电脑知识与技术 2024年7期
关键词:微服务分布式

丁文婷 卜言彬

摘要:随着信息化技术的不断发展,微服务架构成为主流软件开发架构,传统的定时任务存在执行效率低、容错机制差、单点故障无法恢复、管理功能不完善等问题,已渐渐无法满足业务需要。Elastic-Job分布式定时任务框架支持动态注册微服务、分片执行定时任务效率高、容错机制完善、任务管理方便等优点,为海量数据的互联网应用开发提供了很好的解决方案。文章重点对Elastic-Job进行了研究并在互联网企业级系统开发中进行实践,提高了执行的效率和准确率,并且达到了自动化运维的目的。

关键词:定时任务;分布式;Elastic-Job;微服务;自动化运维

中图分类号:TP399      文献标识码:A

文章编号:1009-3044(2024)07-0033-04

开放科学(资源服务)标识码(OSID)

0 引言

定时任务是指按照特定时间周期运行的任务。使用场景为在某个固定时间运行或者周期性地执行某个任务,例如:每天24点做数据汇总,定时发送短信等[1]。傳统的定时任务在单台服务器节点上进行部署,一旦因为网络等原因造成的出错,定时任务将停止执行,这种单点部署的方式存在故障无法恢复、容错机制较差等问题。随着互联网业务的兴起,海量数据处理的定时任务需求越来越多,开发者对定时任务执行效率的需求也在不断提升,例如24点做数据汇总定时发短信的功能要在1小时内完成,若数据量过大,单个节点处理存在效率低下无法满足要求的问题。分布式定时任务的出现很好地解决了以上问题,并提供了可视化界面管理定时任务。Elastic-Job分布式定时任务具有可弹性扩容、多线程处理定时任务效率高、失败容错机制好、具备幂等性等特点,适用于互联网企业海量数据的应用系统服务开发。

1 定时任务框架比对

1.1 Quartz框架

Quartz是由OpenSymphony组织开发的开源且具有丰富特性的任务调度库,主要由Job Detail、Job、Scheduler、Trigger 4个核心类构成[2]。Quartz能创建亦简单亦复杂的调度,具备强大的调度功能与灵活的应用方式,但存在时间规则更改无法实时生效、缺乏容错机制、没有可视化管理界面等缺陷。

1.2 XXL-JOB框架

XXL-JOB将调度行为抽象成一个不承担业务逻辑的调度中心公共平台。平台负责集中管理调度信息,依据调度配置进行调度请求,支持界面化动态配置、任务报警、任务新建、任务修改、任务删除等管理功能,配置完成即刻生效。XXL-JOB通过执行器统一管理拆分的多个JobHandler[3],依据接收到的调度请求,处理相应JobHandler中的业务模块。这种将调度中心和执行器分离的分布式定时任务框架实现了业务逻辑的解耦,提高了项目运行的稳定性、代码的可重用性以及系统的可扩展性。其缺点为依赖MySQL数据库,集群越多锁竞争越大。

1.3 Elastic-Job框架

Elastic-Job是当当网开源的分布式任务调度框架,用于解决分布式任务的协调调度问题,是面向互联网生态和海量任务的适用于互联网场景的分布式调度解决方案。Elastic-Job具有弹性调度、资源管控以及作业治理的功能,并通过开放的架构设计,提供多元化作业生态。Elastic-Job不依赖MySQL数据库,不存在数据库锁竞争的问题。

上述三种定时任务框架的对比如表1所示。

2 Elastic-Job的研究

2.1 Elastic-Job的整体架构

Elastic-Job是基于Zookeeper、Quartz开发的Java分布式定时任务框架,解决了Quartz不支持分布式的问题。该框架主要的功能有支持弹性扩容、通过Zookeeper集中管理和监控Job、支持失效转移等。该项目由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成。

Elastic-Job-Lite定位为轻量级无中心化解决方案,以jar包的形式提供分布式任务的协调服务,其框架结构如图1所示。

App服务器,也称App节点,内含业务的定时任务,以jar的形式集成Elastic-Job-Lite相关组件,配置定时任务相关信息,可集群部署。

Elastic-Job-Lite负责作业的相关调度,产生任务调度记录,Elastic-Job-Lite无中心化,每个节点的作业任务平等且自治,节点间通过注册中心Registry进行分布式调度。

Registry以Zookeeper为注册中心,利用Zookeeper可进行App节点的自动注册和发现的功能特性,以文件的形式保存正在执行的定时任务的基本信息,如IP、定时任务名称、执行时间等,同时利用节点中集成的Elastic-Job进行任务的实例选举。Registry以REST API的形式提供接口供Console组件用于任务的运维管理。

Console为运维管理平台,通过读取Registry中的任务数据,展现任务的执行状态。运维可通过Console查看历史执行任务,修改任务的配置达到控制任务执行的目的,且无须重启App节点,支持定时任务修改热生效。

Elastic-Job-Cloud使用Mesos+Docker的解决方案,额外提供资源治理、应用分发以及进程隔离等功能。

Elastic-Job-Cloud和Elastic-Job-Lite的功能对于定时任务的处理类似,区别如表2所示。

Elastic-Job-Cloud的优势在于Docker[4]部署,对资源细粒度的治理,非常适用于需要削峰填谷的大数据系统。

2.2 作业类型

Elastic-Job提供Simple、Dataflow和Script三种作业类型。

1) Simple类型。Simple作业类型未经任何封装,开发者需实现SimpleJob接口,该接口仅提供execute方法用于任务处理,execute方法定时执行,提供分片号等参数,开发者使用时与Quartz原生接口相似,利用分片号处理对应分片数据。

2) Dataflow类型。Dataflow作业类型用于处理数据流,需实现DataflowJob接口。该接口提供两个方法可供实现,分别用于抓取和处理数据,fetchDate方法抓取要处理的数据,processData方法处理抓取的数据。

3) Script类型。Script作业类型为脚本类型作业,支持Shell、Python、Perl等类型脚本。开发者只需通过控制台或代码配置scriptCommandLine即可,无须编码,执行脚本路径可包含参数,参数传递完毕后,作业框架自动追加最后一个参数作为作业运行时信息。

2.3 作业分片策略

非常耗时的定时任务,例如一次处理一亿条数据,用一个节点可能要处理很久,在互联网领域一般通过横向扩展节点来缩短处理时长,Elastic-Job把作业分为多个分片任务,每个分片交给一个节点去执行,一个节点可处理多个分片,每个分片的处理逻辑可由节点自身决定。

Elastic-Job提供三种任务分片策略,分别为平均分片策略、根据作业名的哈希值奇偶数决定IP升降序算法的分片策略、根据作业名的哈希值对服务器列表进行轮转的分片策略。

平均分配策略为默认策略,也是使用最多的策略。假设有3个App节点处理同一个任务,若任务被分成0~8共9片,则每个App分到的分片为App1=[0,1,2],App2=[3,4,5],App3=[6,7,8]。若任务被分成0-7共8片,则每个App分到的分片为App1=[0,1,6],App2=[2,3,7],App3=[4,5]。若任务被分成0~9共10片,则每个App分到的分片为App1=[0,1,2,9],App2=[3,4,5],App3=[6,7,8]。由此可见,任务的执行时间可缩短约三分之二。

此外分片策略支持自定義扩展,若考虑到App节点每台的负载不同,开发者可自定义策略进行分片任务处理的调整。

2.4 Elastic-Job工作原理

Elastic-Job通过jar包形式集成到App节点,首个节点启动后由监听器触发主节点选举,并使用锁阻塞其他节点执行任务,主节点选举完毕后其他节点方能执行任务。

任一节点启动后节点信息被自动注册到Zookeeper,节点下线时Zookeeper自动更新节点信息。主节点选举、节点上下线、分片总数修改均更新重新分片标记,分片过程中若主节点下线,则先选举主节点,再重新分片。

定时任务触发时,节点首先检查分片标记,若需要重新分片,则通过主节点重新分片,分片过程阻塞,结束后方能执行任务。任务运行过程中只标记重新分片标记而不重新分片,下次任务执行前重新分片。

节点执行完任务后主动抓取未分配的分片任务,并在某节点下线后主动寻找可用的其他节点执行分片,由此实现了分片任务的失效转移,任务不停止执行,从而提高容错性。

2.5 失效转移

Elastic-Job不在执行过程中重新分片,而是等待下次调度之前才重新分片,当任务执行过程中服务器宕机,Elastic-Job允许此次未完成的任务在另一任务节点上补偿执行。

失效转移是当前执行任务的临时补偿执行机制,下次任务运行时,Elastic-Job通过重新分片对当前任务分配进行调整。开启失效转移功能,Elastic-Job将监控作业每一分片的执行状态,并将其写入Zookeeper,供其他节点感知。

一次运行耗时较长且间隔较长的作业场景,失效转移是提升作业运行实时性的有效手段。此外任务本身须具有幂等性,即故障转移到新的节点上执行时,业务数据不能重复执行,已经执行过的数据要在业务代码上进行幂等性的处理,以保证失效转移的正确性。

3 实践和应用

3.1 项目功能描述

互联网电商企业应用开发中,存在上百个微服务模块处理不同的业务,如订单、订购、用户、支付等不同模块,每个模块微服务以集群方式部署,某些定时任务如更新订购关系状态、更新订单状态等任务的处理耗时非常长,任务出错后无法自动恢复,容错机制差,运维工程师期望这些定时任务可通过统一的任务管理平台进行查看和管理,因此引入Elastic-Job-Lite框架。

3.2 Zookeeper部署及其作用

本电商平台Zookeeper部署在Linux环境下,安装JDK1.8及Zookeeper3.6版本,在每个节点创建节点目录、日志目录以及myid文件。

Zookeeper是一个分布式一致性协调服务,是Apache Hadoop下的一个子项目,主要用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。Zookeeper维护一个类似文件系统的树形数据结构,其客户端(如Elastic-Job任务执行实例)可对数据进行读取,每个子目录项如“/app1”都被称作znode目录节点。Zookeeper和文件系统相同,可自由增加、删除znode,可在znode下增加、删除子znode,唯一的不同在于znode可存储数据。

Zookeeper拥有数据监听通知机制,客户端注册监听znode,当znode发生变化,如数据改变、znode被删除、子节点增加删除时,Zookeeper通知所有客户端。

Elastic-Job依赖于Zookeeper进行任务信息存储和主节点选举。任务信息包括任务名称、任务实例节点信息、任务执行策略。在任务的实例节点数量发生变化时,Elastic-Job重新触发选举机制。

3.3 微服务改造

本电商平台微服务采用SpringBoot开发,集成Elastic-Job时须在配置文件中配置任务相关信息和Zookeeper信息,微服务的定时任务处理时根据作业类型实现Elastic-Job提供的不同接口,Simple类型的作业实现SimpleJob接口,Dataflow类型的作业实现DataflowJob接口。

以订购模块的更新订购关系状态的任务为例,采用SimpleJob作业类型,集成Elastic-Job-Lite框架时,须修改以下信息。

1) 配置文件。配置文件须配置注册中心Zookeeper信息以及定时任务相关参数,如:

elasticjob:

#注册中心配置

regCenter:

#Zookeeper的ip和端口

serverLists: localhost:2181

#命名空间,模块名命名分离不同模块的任务

namespace: subscription

#定时任务配置

jobs:

#自定义的任务名称

jobA:

#对应的类

elasticJobClass: com.cucn.job.JobA

cron: 0/10 * * * * ?

#自定义参数

jobParameter:

#分片总数

shardingTotalCount: 3

#自定义的分片参数

shardingItemParameters:

2) 作业任务代码。订单模块的微服务中使用Simple类型的作业实现SimpleJob接口,通过ShardingContext类的getShardingItem方法获取分片号,根据分片号获取该分片要处理的数据并进行处理。例如根据分片号获取订单分表的数据,只须将分片号作为参数传入表名获取该分片对应的分表信息进行处理。

JobA代码如下:

@Component

public class JobA implements SimpleJob {

private final Logger logger = LoggerFactory.getLogger(JobA.class);

@Autowired

private OrderService orderService;

@Override

public void execute(ShardingContext context) {

logger.info("JobA execute start...item: {}|param: {}",

context.getShardingItem(), context.getShardingParameter());

try{

// 通过分片号和参数获取要处理的分表数据

List orders= orderService.findOrders(context.getShardingItem(), context.getShardingParameter());

// 处理数据

for (Order order: orders) {

orderService.setCompleted(order.getId());

}

}

catch(Exception e){

logger.error("JobA execute failed...item={},param={}",context.getShardingItem(), context.getShardingParameter(),e);

}

finally{

logger.info("JobA execute end...");

}

}

}

3.4 任务管理系统的搭建

为方便运维管理各个模块所有处理海量数据的定时任务,本系统须搭建运维统一管理平台Console,该子系统提供可视化界面供运维统一管理定时任务,通过该系统调用注册中心API,可查看和修改任务,任务失败可重新执行,无须重启App节点。该运维统一管理平台界面如图2所示。

Console运维管理平台后端采用Java语言,前端采用HTML、CSS、JS等语言开发,数据库采用MySQL8来持久化作业信息,工程管理工具Maven,集成后将其部署到Linux环境下。

首次搭建Console管理平台需设置全局配置,设置注册中心名称和地址等信息。启动应用后可在Console中查看作业的运行情况。

Console管理平台提供服务器维度和作业维度查看任务的功能。服务器维度可查看接入了Elastic-Job的服务器IP、进程号、运行实例等信息;作业维度可查看各个服务器的定时任务作业名称、作业分片总数、作业运行的时间、作业状态等信息。

Console管理平台可修改作业的信息,服务器维度可将服务器禁用,停止该服务器的定时任务执行,作业维度可修改作业信息,如通过cron表达式修改定时任务的执行时间、修改分片总数、新增自定义参数等,运维工程师只需找到作业名称修改其作业信息即可,修改作业界面如图3所示。

Console运维管理平台还可查看任务的历史调度信息、执行参数和执行信息,进入Console可查看执行日志[5],清晰地掌握每台服务器定时任务的历史执行时长、执行结果。

4 结论

本文重点介绍了Elastic-Job分布式定时任务框架的研究并概述了某大型互联网应用系统上的实践,通过使用Elastic-Job解决了互联网企业在大数据量定时任务作业中处理效率低、容错性差、任务管理不方便等问题,同时保证了系统的高可用性、伸缩性、负载均衡,并提高了容错性。Elastic-Job框架让开发者不再担心任务的线性吞吐量提升等非功能需求,使开发者能够更加专注于业务编码设计,同时Elastic-Job可提高运维工程师的工作效率,使运维不再担心任务的可用性和相关管理需求,只需通过可视化界面操作相关App节点即可轻松管理处理海量数据的定时任务,从而达到了自动化运维的目的。

参考文献:

[1] 陆颖.基于XXL-JOB的可视化分布式定时调度平台的设计与实现[J].电脑知识与技术, 2023,19(14):39-41.

[2] 屈洪雪,陈双,徐海洋.基于Quartz的可视化代理定时任务的研究与设计[J].电子技术与软件工程,2021(18):44-46.

[3] 郑祥,顾丹鹏,陈肖勇.基于XXL-JOB的分布式定時任务研究和应用[J].计算机时代,2002(5):80-82.

[4] 段诩,张文辉.基于Docker集群的分布式动作教学平台设计[J].电子设计工程,2020,28(23):63-67,72.

[5] 潘平平.基于松耦合架构的分布式定时任务调度系统的设计与实现[D].南京:东南大学,2020.

【通联编辑:王 力】

猜你喜欢

微服务分布式
分布式光伏发展的四大矛盾
分布式光伏热钱汹涌
基于预处理MUSIC算法的分布式阵列DOA估计
分布式光伏:爆发还是徘徊
基于供给侧改革理论的图书馆社交网络微服务研究
微信公众平台在医院图书馆的应用现状调查
基于微信企业号的校园移动服务
微服务视角下高职图书馆数字资源使用分析
从单一模式系统架构往微服务架构迁移转化技术研究
基于微信公众平台的高校图书馆微服务现状及对策