分布式任务调度(04)--自研

2023-11-08 10:06:16 浏览数 (1)

1 背景

兼容技术团队自研的RPC框架,技术团队不需要修改代码,RPC注解方法可以托管在任务调度系统中,直接当做一个任务来执行。

研读XXL-JOB,同时从阿里云分布式任务调度 SchedulerX 吸取。

SchedulerX 1.0 架构图

  • Schedulerx-console 是任务调度的控制台,用于创建、管理定时任务。负责数据的创建、修改和查询。在产品内部与 schedulerx server 交互。
  • Schedulerx-server 是任务调度的服务端,是 Scheduler的核心组件。负责客户端任务的调度触发以及任务执行状态的监测。
  • Schedulerx-client 是任务调度的客户端。每个接入客户端的应用进程就是一个的 Worker。Worker 负责与 Schedulerx-server 建立通信,让 schedulerx-server发现客户端的机器。并向schedulerx-server注册当前应用所在的分组,这样 schedulerx-server才能向客户端定时触发任务。

我们模仿了SchedulerX的模块,架构设计如下图:

选择 RocketMQ 源码的通讯模块 remoting 作为自研调度系统的通讯框架:阅读 SchedulerX 1.0 client 源码中,发现 SchedulerX 的通讯框架和RocketMQ Remoting很多地方都很类似。它的源码里有现成的工程实现。

将 RocketMQ remoting 模块去掉名字服务代码,做定制。

在RocketMQ的remoting里,服务端采用 Processor 模式。

调度中心需要注册两个处理器:回调结果处理器CallBackProcessor和心跳处理器HeartBeatProcessor 。执行器需要注册触发任务处理器TriggerTaskProcessor 。

代码语言:javascript复制
public void registerProcessor(
             int requestCode,
             NettyRequestProcessor processor,
             ExecutorService executor);1.2.3.4.

处理器的接口:

代码语言:javascript复制
Explainpublic interface NettyRequestProcessor {
 RemotingCommand processRequest(
                 ChannelHandlerContext ctx,
                 RemotingCommand request) throws Exception;
 boolean rejectRequest();
}1.2.3.4.5.6.

对于通讯框架来讲,我并不需要关注通讯细节,只需要实现处理器接口即可。

以触发任务处理器TriggerTaskProcessor举例:

搞定网络通讯后,调度器如何设计 ?最终我还是选择了Quartz 集群模式。主要是基于以下几点原因:

  1. 调度量不大的情况下 ,Quartz 集群模式足够稳定,而且可以兼容原来的XXL-JOB任务;
  2. 使用时间轮的话,本身没有足够的实践经验,担心出问题。另外,如何让任务通过不同的调度服务(schedule-server)触发, 需要有一个协调器。于是想到Zookeeper。但这样的话,又引入了新的组件。
  3. 研发周期不能太长,想快点出成果。

自研版的调度服务花费一个半月上线了。系统运行非常稳定,研发团队接入也很顺畅。调度量也不大 ,四个月总共接近4000万到5000万之间的调度量。

自研版的瓶颈,我的脑海里经常能看到。数据量大,我可以搞定分库分表,但 Quartz 集群基于行级锁的模式 ,注定上限不会太高。

2 实战

  1. 去掉外置的注册中心,调度服务(schedule-server)管理会话;
  2. 引入zookeeper,通过zk协调调度服务。但是HA机制很粗糙,相当于一个任务调度服务运行,另一个服务standby;
  3. Quartz 替换成时间轮 (参考Dubbo里的时间轮源码)。

这个Demo版本在开发环境可以运行,但有很多细节需要优化,仅仅是个玩具,并没有机会运行到生产环境。

最近读阿里云的一篇文章《如何通过任务调度实现百万规则报警》,SchedulerX2.0 高可用架构见下图:

文章提到:

每个应用都会做三备份,通过 zk 抢锁,一主两备,如果某台 Server 挂了,会进行 failover,由其他 Server 接管调度任务。

这次自研任务调度系统从架构来讲,并不复杂,实现了XXL-JOB的核心功能,也兼容了技术团队的RPC框架,但并没有实现工作流以及mapreduce分片。

SchedulerX 在升级到2.0之后基于全新的Akka 架构,这种架构号称实现高性能工作流引擎,实现进程间通信,减少网络通讯代码。

在我调研的开源任务调度系统中,PowerJob也是基于Akka 架构,同时也实现了工作流和MapReduce执行模式。

3 技术选型

首先我们将任务调度开源产品和商业产品 SchedulerX 放在一起,生成一张对照表:

Quartz 和 ElasticJob从本质属于框架。

中心化产品从架构上来讲更加清晰,调度层面更灵活,可以支持更复杂的调度(mapreduce动态分片,工作流)。

XXL-JOB 从产品层面已经做到极简,开箱即用,调度模式可以满足大部分研发团队的需求。简单易用 能打,所以非常受大家欢迎。

其实每个技术团队的技术储备不尽相同,面对的场景也不一样,所以技术选型并不能一概而论。

  • 幂等。当任务被重复执行的时候,或者分布式锁失效的时候,程序依然可以输出正确的结果;
  • 任务不跑了,千万别惊慌。查看调度日志,JVM层面使用Jstack命令查看堆栈,网络通讯要添加超时时间 ,一般能解决大部分问题。

参考

  • https://xie.infoq.cn/article/ca1973d9c00fae8a747fd5b9f
  • https://www.51cto.com/article/707369.html

0 人点赞