首页 > 其他分享 >分布式任务调度(04)--走上魔改

分布式任务调度(04)--走上魔改

时间:2023-11-09 20:31:53浏览次数:35  
标签:任务调度 04 魔改 调度 server 任务 处理器 SchedulerX

1 背景

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

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

img

SchedulerX 1.0 架构图

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

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

img

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

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

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

img

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

public void registerProcessor(
             int requestCode,
             NettyRequestProcessor processor,
             ExecutorService executor);1.2.3.4.

处理器的接口:

Explainpublic interface NettyRequestProcessor {
 RemotingCommand processRequest(
                 ChannelHandlerContext ctx,
                 RemotingCommand request) throws Exception;
 boolean rejectRequest();
}1.2.3.4.5.6.

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

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

img

搞定网络通讯后,调度器如何设计 ?最终我还是选择了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里的时间轮源码)。

img

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

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

img

文章提到:

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

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

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

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

3 技术选型

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

img

Quartz 和 ElasticJob从本质属于框架。

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

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

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

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

参考

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

标签:任务调度,04,魔改,调度,server,任务,处理器,SchedulerX
From: https://blog.51cto.com/JavaEdge/8285360

相关文章

  • Day04-Java开发所需的前端技术
    HTTP请求请求行请求头请求体JavaScript函数一个字母占一个字节,一个汉字占三个字节//获取长度"字符串".length//获得字符串的urIEncode编码(特殊字符需要编码)encodeURIComponent("张三")//编码结果%E5%BC%A0%E4%B8%89get请求示例GET/test?name=zhang&age=18HTTP/1.1Host:lo......
  • 调整ubuntu20.04交换分区
    free-h#查看交换分区sudofallocate-l8G/swapfile提示:fallocate失败,文本文件忙,需先关闭交换分区sudoswapoff/swapfile再依次执行以下命令:sudofallocate-l8G/swapfilesudochmod600/swapfilesudomkswap/swapfilesudoswapon/swapfile......
  • LeetCode_0042. 接雨水
    题目描述给定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。示例示例1:输入:height=[0,1,0,2,1,0,1,3,2,1,2,1]输出:6解释:上面是由数组[0,1,0,2,1,0,1,3,2,1,2,1]表示的高度图,在这种情况下,可以接6个单位的雨水(蓝色部分表示雨......
  • ubuntu22.04挂载windows的smb3文件共享
    现在windows一般使用smb3.0版本 可以看到,支持smb3直接编辑/etc/fstab 如果目标目录有空格,可以用\040进行转义,通常的转义在这儿不管用。/etc/cirfs-credentials用于配置用户名密码  手动挂载可以使用sudomount.smb3//192.168.31.20/samba /mnt/samba-ousername......
  • 04-栈和队列
    4.栈和队列栈:push,pop,peek(返回当前值),empty队列:add,remove,peek(返回当前值),isEmpty4.1双向链表实现栈和队列4.2数组实现栈和队列加一个指针指向某个位置。队列:环形数组4.3最小栈1.题目https://leetcode.cn/problems/min-stack/设计一个支持push,pop,top操作,并能在常数......
  • 分布式任务调度(03)--中心化设计
    把调度和任务执行,隔离成两个部分:调度中心只需要负责任务调度属性,触发调度命令执行器执行器接收调度命令,去执行具体的业务逻辑两者都可以进行横向扩容。1MQ调度中心依赖Quartz集群模式,当任务调度时,发送消息到RabbitMQ。业务应用收到任务消息后,消费任务信息。充分利......
  • React—04—状态管理
     有时候你希望两个组件的状态始终同步更改。要实现这一点,可以将相关状态从这两个组件上移除,并把这些状态移到最近的父级组件,然后通过props将状态传递给这两个组件。这被称为“状态提升”,这是编写React代码时常做的事。 事件一般以onXXX开头,比如内置元素div的click事件......
  • 洛谷P3046 海底高铁 巧用差分统计经过区间次数
    洛谷P3046海底高铁-差分统计经过区间次数题目贴在这里P3406海底高铁-洛谷|计算机科学教育新生态(luogu.com.cn)分析本题题干很长,但是题意理解很简单。就是给定n个节点,每次仅能在相邻的两个节点之间移动,且任意两个节点之间的高铁费用也不一样。依据题意,假设从3节点到1......
  • 从零开始构建报警中心:part04 钉钉消息-webhook
    现在工作上比较常用的IM一般式钉钉企微飞书,其实使用起来都是大同小异的。这里就用钉钉来实现。使用钉钉发送信息,一般有三种形式群webhook工作通知智能机器人智能机器人方式,能实现一定的交互功能,但逻辑相对复杂,这里只是需要一个实时的钉钉消息,所以不进行讨论。添加群webhook这是一......
  • SP15637 GNYR04H - Mr Youngs Picture Permutations(线性 dp)
    题目求方案数,考虑dp——状态设计和边界——题目告诉了一个很显然的性质:每一排从左至右保证高度单调递减每一列从后往前保证高度单调递减那么可以发现,对于每一行,每一列,一定是按高度顺序插入,并且是连续插入,因为如果不连续,就无法保证单调递减的性质同时,它给出了另一个性......