【分布式任务调度】XXL-JOB调度中心对执行器的上下线感知实现原理(三)

news2024/11/27 8:41:18

文章目录

  • 1. 前言
  • 2. 调度关系
  • 3. 执行器注册
    • 3.1. 调度中心处理注册请求
    • 3.2. 执行器发起注册请求
  • 4. 执行器注销
    • 4.1.主动注销
    • 4.2. 被动注销
  • 5.流程图
  • 6. 总结

1. 前言

XXL-JOB专题历史文章列表:

  • XXL-JOB调度中心集群部署配置(一)
  • XXL-JOB执行器配置及定时任务的创建(二)

在前面两篇文章内容中,我们已经获取到了一个XXL-JOB的集群,以及一个可以执行任务的调度器,同时,在实际的项目中可以参照这个流程,引入定时任务。

接下来,我们就可以探索一下调度中心对执行器的上下线感知实现原理,主要包括以下几点:

  • 执行器注册流程
  • 执行器的注销流程
  • 调度中心探活流程

在运行过程中,调度中心要对执行器进行调度,得先获取到执行器的信息,才能根据信息发起调度请求,同时,我们又不希望因调度中心调用到已宕机的执行器而导致程序异常。

于是,XXL-JOB在调度中心中,维护了一个注册中心,通过xxl_job_registry这张表来实现的,调度中心每次发起调度请求时,都会通过这张表中的数据来做负载均衡。那么,只需要做到将活跃的执行器信息注册上去,并在执行器停机或宕机后,将其从注册中心中移除,这样,调度中心就获得了对执行器的上线下感知。

2. 调度关系

定时任务是如何被调用的呢?
我们先看一个分层结构图,XXL-JOB的调度关系分为了3层,每层向下进行调度,最上层是调度中心,最下层是定时任务需要执行的方法,调度中心可以调度不同的执行器,执行器再调用归属于自己的定时任务,如下图所示:
在这里插入图片描述

调度中心在调度执行器时,需要知道执行器的ip和端口号,以此来找到对应的执行器节点来进行调度。而调度中心获取到执行器ip的方式有两种,分别是:自动注册、手动录入。

一般不会使用手动录入的方式,为什么呢?可以想象一下,在新增、减少了执行器实例,执行器宕机时,都需要手动修改机器地址,意味着需要有人24小时盯着,这是一件很可怕的事。

所以,正常情况下我们都会选择使用自动注册的方式来创建,选择这种方式的话,就需要调度中心与执行器之间建立通信机制,通过网络请求传输注册信息。
注:下面是在后台管理系统中的配置。
在这里插入图片描述

3. 执行器注册

当前版本(2.3.1)的XXL-JOB采用的是Http通信,而调度中心是通过SpringBoot来实现的。
实际上,调度中心就是启动了一个Tomcat,并提供了执行器注册接口。执行器在启动的时候就会调用这个接口,将自己的ip,端口等信息传输到调度中心,再由调度中心存入数据库中,这样就完成了执行器注册。

3.1. 调度中心处理注册请求

首先,需要调度中心向外暴露的注册接口位置。
XXL-JOB项目中的的命名还是比较规范的,我们可以在xxl-job-admin的contoller包中去搜索,很容易找到一个api相关的Controller接口JobApiController,进入到这个类中。
果然,在这个类里面有一个api相关的方法,如下:
在这里插入图片描述

这是一个RESTFUL接口,包含了三个策略路径,分别是:callback,registry,registryRemove,通过语义,可以大胆的猜测registry这条路径就是注册操作,registryRemove是注销操作,而callback是执行器的执行结果回调(本篇暂不关注回调接口)。
我们通过registry的路径一路顺藤摸瓜,就找到了实际做注册动作的方法:
在这里插入图片描述

图中红框显示的就是一个简单的saveOrUpdate方法,只是这里用异步来做了,很好理解:

  • getXxlJobRegistryDao():表示获取xxl_job_registry这张表对应的dao对象。
  • registrySave:创建一条执行器注册数据。
  • registryUpdate:更新执行器信息,这个操作是用来维持心跳连接的。

简单的说,就是调度中心会接收执行器的registry请求,然后将请求中传入的参数保存到xxl_job_registy表中。这就是调度中心运行的执行器注册主流程,一个非常简单的CRUD。

看完了主流程之后,我们再来看一下细节,可以发现这里的注册代码并不是同步执行的,而是通过一个线程池registryOrRemoveThreadPool来进行的异步操作。这里也体现了XXL-JOB的一个设计思想,即全异步化调用,我们在研究后续原理的时候,还会经常看到这样的用法。

registryOrRemoveThreadPool的创建
registryOrRemoveThreadPool这个线程池是项目启动时提前创建好的,通过Idea的usages可以找到,选中代码中的registryOrRemoveThreadPool使用快捷键alt+F7,可以打开下图所示的界面,找到一个new ThreadPoolExecutor()的地方,这就创建线程池位置。
在这里插入图片描述

点击红框中的内容,可以跳转到创建这个线程池的那一行代码查看线索池信息了。
在这里插入图片描述

这里还可以进一步查看XXL-JOB的配置初始化过程,使用alt+鼠标左键查看start()方法的使用位置。
在这里插入图片描述

可以看到这里做了各种各样的初始化操作,后续想了解XXL-JOB中的某个流程的话,就可以以这里的初始化操作为线索,找到对应的代码流程,在后续的源码探索中,还会多次进入这个位置。

3.2. 执行器发起注册请求

所谓的执行器,实际上就是一个引入了xxl-job-core包的Spring-Web项目,在上一篇的内容中,我们在代码中只写了一个@XxlJob注解就完成了一个定时任务方法,就是因为大部分工作都是由xxl-job-core这个包来完成的,现在我们可以去探索一下,执行器是如何注册到调度中心的。

在上面xxl-job-admin中的注册接口吗,在这个接口中使用了一个AdminBiz接口,进入到这个接口中,找到registry方法,它有两个实现:

  • 一个在xxl-job-admin中,这是上面已经讲到的调度中心实现注册的方法。
  • 另一个在xxl-job-core中,这就是执行器发起注册请求的位置。
    在这里插入图片描述

我们可以通过注册请求倒推回去,可以找到一个ExecutorRegistryThread类:
在这里插入图片描述

上图红框中的内容展示了是通过appName与address组成了一个请求参数,然后将这个参数传输到了xxl-job-admin中,这就是执行器注册的入口。这里可以注意一下while(!toStop),说明当前的registryThread线程会循环调用注册方法,还记得上面的registryUpdate吗?
我们说这个是用来维持心跳连接的,那么心跳请求是多长时间发送一次呢?可以把代码往下拉:
在这里插入图片描述
在这里插入图片描述

通过XXL-JOB的架构,我们已经知道在执行器启动之后,需要调度中心的来做任务调度,而调度中心需要知道执行器的标识以及IP地址、端口,才能对指定的执行器发送调度请求。这也是为什么上图中的请求参数中会有appName和address。

既然执行器把地址交给了调度中心,很自然的可以想到,在交出地址之前,执行器会按照这个地址启动一个供调度中心调用的web服务。

继续往外层跳,可以找到web服务的启动代码,这里使用的是netty。
在这里插入图片描述

综上,执行器这边的主要流程可以通过一张简图来表示:
在这里插入图片描述

4. 执行器注销

执行器的注销分为主动注销和被动注销两种。

  • 主动注销:顾名思义,就是执行器向调度中心发送注销请求,调度中心接收后把这个执行器的注册信息删除掉。
  • 被动注销:就是执行器以外宕机后,无法正常的向调度中心发送注销请求,由调度中心的探活线程发现了某个执行器已下线,此时将该执行器的注册信息删除掉。

4.1.主动注销

主动注销的发起时机是在Spring容器正常关闭时,XXL-JOB的执行器类XxlJobSpringExecutor实现了DisposableBean接口,这个接口提供了一个destory方法。
在这里插入图片描述

在后续的流程中,会停止Netty服务,中断探活线程,并向调度中心发送removeRegistry请求。
在这里插入图片描述

在这里插入图片描述

stop的状态修改后,这里的探活循环就会停止,进而会调用到下面的registryRemove方法。
调度中心收到请求后,也会通过registryOrRemoveThreadPool线程池进行异步处理,最终将xxl_job_registry中对应的执行器信息删除掉。

4.2. 被动注销

调度中心初始化时,会启动一个监控线程registryMonitorThread,这个线程每30秒会触发一次探活操作(即每循环一次sleep 30秒),探活操作触发时会查询xxl_job_registry表中的数据,将update_time与当前时间的差值大于90s的数据查询出来,将这部分数据删掉掉。
在这里插入图片描述

把sleep的时间差也考虑进去的话,就是执行器在最多120秒内都没有发送新的注册请求来维持心跳的话,这个执行器就会被调度中心注销掉。
心跳是怎么维持的呢?
看了上面执行器发起注册的流程,大概也能猜到了,执行器里面的registryThread每30秒会调用一次调度中心的注册接口,调度中心收到请求后,更新update-time的值。
在这里插入图片描述

5.流程图

经过上面的探索,我们已经了解了执行器的注册与注销的流程,下面是这整个流程的流程图。
在这里插入图片描述

6. 总结

本篇内容主要是在探索执行器注册到调度中心的流程以及代码实现,流程如下:

  1. 调度中心启动了一个Tomcat作为Web容器,暴露出注册与注销的接口,可以供执行器调用。
  2. 执行器在启动Netty服务暴露出调度接口后,将自己的name、ip、端口信息通过调度中心的注册口传输到调度中心,同时每30秒会调用一次注册接口,用于更新注册信息。
  3. 同理,在执行器停止的时候,也会请求调度中心的注销接口,进行注销。
  4. 调度中心在接收到注册或注销请求后,会操作xxl_job_registry表,新增或删除执行器的注册信息
  5. 调度中心会启动一个探活线程,将90秒都没有更新注册信息的执行器删除掉。

由于本篇只是在探索注册与发现的流程,所以忽略在这个流程中还涉及到的任务调度与回调相关的逻辑,这部分逻辑将在下一篇调度流程原理分析中讲到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

官宣!Databend Cloud 和青云科技达成合作

近日,北京数变科技有限公司与北京青云科技股份有限公司(以下简称:青云科技 )顺利完成了产品兼容性适配互认证。本次测试是对 Databend 云原生数据仓库系统与青云科技公司自主研发的 QingStor U10000 进行严格的联合测试验证。测试结果显示&am…

数字 IC 设计职位经典笔/面试题(二)

共100道经典笔试、面试题目(文末可全领) FPGA 中可以综合实现为 RAM/ROM/CAM 的三种资源及其注意事项? 三种资源:BLOCK RAM,触发器(FF),查找表(LUT)&#xf…

CAS机制详解

一、是什么 CAS,是Compare and Swap的简称,实现并发算法是常用到的一种技术,在这个机制中有三个核心的参数。 主内存中存放的共享变量的值:V(一般情况下这个V是内存的地址值,通过这个地址可以获得内存中的…

mysql数值函数

1. ceil() 向上取整 2. floor() 向下取整 3. mod() 取余 4. rand() 生成0-1之间的随机数 5. round(x,y) x 四舍五入,保留 y 位小数

【Spring core学习三】对象装配:获取Bean对象的四种方式

目录 对象装配的四种方式 🌷1、Autowired属性注入(使用最多) 🌷2、Setter注入 🌷3、构造函数注入 🌷4、Resource:另⼀种注⼊关键字 对象装配的四种方式 对象装配:获取bean对象也…

2、用phpMyAdmin修改mysql的密码

用phpMyAdmin登录mysql服务器,默认的用户名密码为 Username: root Password: [null] 在账户中修改密码

8.分布式存储

文章目录 分布式存储存储基础单机存储设备单机存储的问题分布式存储(软件定义的存储 SDS)分布式存储的数据类型总结 CephCeph概念Ceph优势Ceph架构Ceph核心组件OSD 存储后端Ceph 数据的存储过程Ceph 版本发行生命周期Ceph 集群部署Ceph 生产环境推荐&…

虚拟机磁盘扩容

工作中已经不止一次碰到虚机扩容了,所以一定要切记:给虚机多分配些容量!! 方法其实就是现在物理机上给磁盘扩容,然后再跑到虚拟机内部进行lvm卷扩容,具体的原理到去看LVM底层,总体就是LV->V…

我做了10年的测试,由衷的建议年轻人别入这行了...

两天前,有个做功能测试7年的同事被裁员了。这位老哥已经做到了团队中的骨干了,人又踏实,结果没想到刚刚踏入互联网“老龄化”大关,就被公司给无情优化了。 现在他想找同类型的工作,薪资也一直被压,考虑转行…

leetcode-541. 反转字符串 II

leetcode-541. 反转字符串 II 文章目录 leetcode-541. 反转字符串 II一.题目描述二.第1次提交(for循环,std::reverse)三.第2次提交四.第3次提交五.第4次提交六.代码随想录解答一七.代码随想录解答二八.代码随想录解答三 一.题目描述 二.第1次提交(for循环&#xff0…

安达发|APS排程系统能帮医药行业实现哪些目标

高级发展规划和调度aps (advanced planning and scheduling)是一个国家基于中国整个社会企业进行生产经营活动的计算机信息系统。通过aps的管理手段和信息,企业可以优化从产品产量的决定到最终产品管理的所有生产过程。利用实时,准…

10大功能特性,助力开发者玩转华为云API Explorer

伴随着我国API生态逐渐成熟、市场发展不断完善,API已广泛应用在以网页、移动应用、后端系统集成为主的众多开发场景中。同时,开发者对API的主要诉求已由获取数据能力转变为获取技术能力、甚至业务能力,开发者渴望更加高效便捷的调用方式&…

CRMEB商城系统授权与不授权有什么区别

现在,很多时候我们都会听到“授权”这个词,在CRMEB的商城系统产品中,商业授权也是一个重要环节,今天,我们就来了解一下关于CRMEB商城系统授权的那些事儿。 一、为什么要进行商业授权? 正版商业授权是对用户…

MVVM 实现记录文本

1. MVVM 框架说明: Model - 数据层 View - 视图层 ViewModel - 管理模型的视图 2. 资源文件 2.1 启动图标: AppIconhttps://img-blog.csdnimg.cn/8fa1031489f544ef9757b6b3ab0eddbe.png 2.2 Display Name: Do Stuff 2.2 颜色图: 2.3 项目结构图: 3. Model 层实现&a…

2.8 Bootstrap 图片

文章目录 Bootstrap 图片\<img> 类响应式图片 Bootstrap 图片 在本章中&#xff0c;我们将学习 Bootstrap 对图片的支持。Bootstrap 提供了三个可对图片应用简单样式的 class&#xff1a; .img-rounded&#xff1a;添加 border-radius:6px 来获得图片圆角。.img-circle&…

探索uni-app:构建跨平台应用的神奇工具

文章目录 &#x1f4da;1. 视图容器类组件⚡ <view>&#xff1a;视图容器&#xff0c;类似于div元素⚡<scroll-view>&#xff1a;可滚动的视图容器 &#x1f4da;2. 基础内容类组件⚡<text>&#xff1a;文本内容&#xff0c;类似于span元素⚡<icon>&am…

阿里大佬都在偷偷肝的 Java 程序优化笔记,程序性能提高了 5 倍!

前言 此笔记从软件设计、编码和 JVM 等维度阐述性能优化的方法和技巧&#xff0c;分享资深架构师 Java 程序性能优化的宝贵经验&#xff0c;专注于 Java 应用程序的优化方法、技巧和思想&#xff0c;并深度剖析 JDK 部分的实现。具有较强的层次性和连贯性&#xff0c;深入剖析…

wps插入图片显示不全、混乱

问题如下&#xff1a; 原因&#xff1a; 格式混乱 解决办法&#xff1a; 1、统一格式&#xff0c;使用格式刷统一文档的格式 2、Ctrl A 全选&#xff0c;重新选择行距 3、重新粘贴图片&#xff08;选择嵌入型&#xff09;

什么是事件循环 Event Loop

一、什么是事件循环 事件循环&#xff08;Event Loop&#xff09;是单线程的JavaScript在处理异步事件时进行的一种循环过程&#xff0c;具体来讲&#xff0c;对于异步事件它会先加入到事件队列中挂起&#xff0c;等主线程空闲时会去执行事件队列&#xff08;Event Queue&…