PowerJob容器的今生,容器是如何部署到Worker上,并正常运行的

news2024/11/26 8:31:18

这仅仅是一篇PowerJob源码分析的文章,但是也有一些java基础知识,在实践中学习效果更好,感兴趣就留下来交流一下吧。

上回书说到,这个powerjob容器是如何生成模板,如何上传到服务器上去,本回主要总结的是,worker是如何部署执行容器的。其实我在寻找部署的入口的时候,还是费了一番功夫的,因为这个部署按钮,他居然不在containerController里面,而是在另外一个类里面,害我一顿好找,差一点就放弃了。

一切的开始:容器的部署

这个部署的入口,居然使用的是websocket,在server.web.websocket包下的ContainerDeployServerEndpoint类中,当你点击前台页面中某个容器的部署按钮时,就会触发该类下面的onOpen方法,调用ContainerService的deploy方法。

调用deploy方法之后,前面已经讲过,会向worker的WorkerActor发送一条命令,让其对容器进行部署,当然worker是一个列表。

WorkerActor接到命令之后,操作的步骤如下:

1. 判断是否是重复部署

Long containerId = request.getContainerId();
String containerName = request.getContainerName();
String version = request.getVersion();

OmsContainer oldContainer = CARGO.get(containerId);
if (oldContainer != null && version.equals(oldContainer.getVersion())) {
    return;
}

2. 如果不是重复部署,创建容器jar包

String filePath = CONTAINER_DIR + containerId + "/" + version + ".jar";
File jarFile = new File(filePath);

3.判断jar包文件是否存在,如果不存在,则从server端下载jar包

if (!jarFile.exists()) {
    FileUtils.forceMkdirParent(jarFile);
    FileUtils.copyURLToFile(new URL(request.getDownloadURL()), jarFile, 5000, 300000);
    log.info("[OmsContainer-{}] download jar successfully, path={}", containerId, jarFile.getPath());
}

 4.创建新容器

OmsContainer newContainer = new OmsJarContainer(containerId, containerName, version, jarFile);
newContainer.init();

初始化里面,需要自定义一个类加载器

public class OhMyClassLoader extends URLClassLoader

通过解析下载jar包中的配置文件“oms-worker-container.properties”获取jar包的路径,通过路径和自定义的类加载器的合作,将容器的类进行一个动态加载

// 解析 Properties
Properties properties = new Properties();
try (InputStream propertiesURLStream = containerClassLoader.getResourceAsStream(ContainerConstant.CONTAINER_PROPERTIES_FILE_NAME)) {

    if (propertiesURLStream == null) {
        log.error("[OmsJarContainer-{}] can't find {} in jar {}.", containerId, ContainerConstant.CONTAINER_PROPERTIES_FILE_NAME, localJarFile.getPath());
        throw new PowerJobException("invalid jar file because of no " + ContainerConstant.CONTAINER_PROPERTIES_FILE_NAME);
    }

    properties.load(propertiesURLStream);
    log.info("[OmsJarContainer-{}] load container properties successfully: {}", containerId, properties);
}
String packageName = properties.getProperty(ContainerConstant.CONTAINER_PACKAGE_NAME_KEY);
if (StringUtils.isEmpty(packageName)) {
    log.error("[OmsJarContainer-{}] get package name failed, developer should't modify the properties file!", containerId);
    throw new PowerJobException("invalid jar file");
}

// 加载用户类
containerClassLoader.load(packageName);

通过spring的IOC容器将类进行加载

ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(containerClassLoader);
try {
    this.container = new ClassPathXmlApplicationContext(new String[]{ContainerConstant.SPRING_CONTEXT_FILE_NAME}, false);
    this.container.setClassLoader(containerClassLoader);
    this.container.refresh();
}finally {
    Thread.currentThread().setContextClassLoader(oldCL);
}

5.  将新的容器保存在内存中

CARGO.put(containerId, newContainer);

6. 将旧的容器销毁

if (oldContainer != null) {
    // 销毁旧容器
    oldContainer.destroy();
}

到这里,容器的部署就算是结束了。

平淡无奇:容器的执行

讲过本篇文章和上一篇文章,在经历了容器模板的生成下载,容器的开发与上传,容器的部署之后,容器就可以正常使用了,这个时候就需要在任务管理里面添加任务了!

 

需要将执行配置添加好,容器ID#加全限定名,添加好了之后,点击运行,进入任务实例界面查看运行结果!

 

总结

 至此,容器的前世今生就全部结束了,不知道看完了这些之后,你是否会有所收获,我最大的收获就是,当我的某个流程或者系统需要新增功能时,完全可以用到这里面的思想,不过这个东西不宜过多使用,否则会因为添加的容器过多,而不好管理。

 

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

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

相关文章

死磕Node模块兼容性,ESM和CJS我全都要!

目录 前言 一些概念 CJS(CommonJS) ESM(ECMAScript Modules) 兼容操作 效果演示 总结 前言 在Node版本13.2.0(2019年)之前,我们一般使用CJS(CommonJS)模式在代码…

Java JDBC详解

1、JDBC概念、本质、好处 概念: JDBC 就是使用Java语言操作关系型数据库的一套API 全称:( Java DataBase Connectivity ) Java 数据库连接 本质: 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口…

展现AI与自动化测试技术之间的神奇化学反应

目录 零:前言 一、介绍 1.1、什么是自动化测试技术 1.2、痛点 1.3、几款优秀的自动化测试工具介绍 1.3.1、Selenium 1.3.2、龙测AI-TestOps云平台 1.3.3、TestCafe 二、实操 2.1、主要功能模块介绍 2.2、实战演练 2.2.1、创建web项目 2.2.2、录制流程图…

Taro3.x 容易踩坑的点(阻止滚动穿透,弹框蒙层父级定位)

解决弹框滚动的时候,下层也会滚动问题》阻止滚动穿透(react,vue)案例描述:页面展示时需要滚动条才可以显示完整,但是当我们显示弹框的时候,即使不需要滚动条,但是页面仍然可以滚动,并且下层内容会随着滚动变…

MES助力灯具照明行业从制造到”智造”

现如今,LED照明行业产品更新换代太快,一个产品一两年不更新一下外观、材料,就会被对手超越。这直接导致LED产品标准化程度不够高,LED下游制造类厂家智能化生产程度普遍偏低。 加之大多属于劳动密集型产业,传统的依靠买…

Hive分区表与分桶表的使用具体说明

目录 一、分区表 (一)分区表基本语法 1.创建分区表 2.往分区表中写入数据的两种方法 (1)load装载本地数据 (2)insert...select...(常用) 3.读取分区表数据 4. Hive分区表的存储路径规划:分区字段分区值 5.分区表基本操作 (1)查看所有分区信息 (2)新增分区…

C#使用MQTT通信 .Net实现MQTT通信 java使用MQTT通信 java实现MQTT通信

MQTT是一种轻量级、基于发布/订阅模式的通信协议,通常用于物联网设备间的通信。MQTT协议采用简单的二进制消息格式,能够在不占用过多网络带宽的情况下进行高效的通信。以下是使用MQTT进行通信的一些基本概念:BrokerMQTT通信中的中间件&#x…

机器学习算法: AdaBoost 详解

1. 集成学习概述 1.1. 定义 集成学习(Ensemble learning)就是将若干个弱分类器通过一定的策略组合之后产生一个强分类器。 弱分类器(Weak Classifier)指的就是那些分类准确率只比随机猜测略好一点的分类器,而强分类器&…

住宅防雷接地的选择要求和施工方法

在您家的布线系统中,防雷接地系统是一项至关重要的安全功能。如果系统发生某种故障,接地系统提供电阻最小的路径,确保电流安全地流回大地本身。因此,它减少了短路导致火灾或危及生命的电击的可能性。家庭接地系统的最后一个也是最…

成都的Java培训机构有哪些?

强烈自荐 二十三年教学实力积累 "课工场是专注互联网教育的生态平台,汇聚中国和北美数百位来自互联网企业的行业大咖,向寻求技术提升和想进入IT行业的人群提供直播、录播、线下面授等多模式教学服务,并通过全国线下服务中心提供更加成熟…

【JVM】内存结构

【JVM】内存结构 文章目录【JVM】内存结构1. 程序计数器1.1 定义1.2 作用2. 虚拟机栈2.1 定义2.2 栈内存溢出2.3 线程运行诊断3. 本地方法栈4. 堆4.1 定义4.2 堆内存溢出4.3 堆内存诊断5. 方法区5.1 定义5.2 组成5.3 方法区内存溢出5.4 运行时常量池5.5 StringTable特性1. 程序…

Hadoop集群模式安装(Cluster mode)

1、Hadoop源码编译 安装包、源码包下载地址 Index of /dist/hadoop/common/hadoop-3.3.0为什么要重新编译Hadoop源码? 匹配不同操作系统本地库环境,Hadoop某些操作比如压缩、IO需要调用系统本地库(*.so|*.dll) 修改源码、重构源码 如何…

电子墨水屏的应用场景

电子纸挺好个东西,大家都把注意力集中在商超场景,其实还有更多有趣的场景方案可用,价值也不小,比如: 仓库场景:通过亮灯拣选,提高仓库作业效率。 仓库循环使用标签:做NFC类发卡式应…

CnOpenData专精特新“小巨人”企业工商注册基本信息数据

一、数据简介 “专精特新”一词最早来源于2011年7月,由时任工信部总工程师朱宏任在《中国产业发展和产业政策报告(2011)》新闻发布会上首次提出。“专精特新”是指具备专业化、精细化、特色化、创新型四大优势的企业。根据工信部的定义&#…

content-type几种常见类型区别

Content-Type叫做MIME(mediaType)类型,使用Content-Type来表示请求和响应中的媒体类型信息。如果是请求头,它用来告诉服务端如何处理请求的数据,如果是响应头,它用来告诉客户端(一般是浏览器)如…

numpy的常见数据类型

常见数据类型介绍Python 原生的数据类型相对较少, bool、int、float、str等。这在不需要关心数据在计算机中表示的所有方式的应用中是方便的。然而,对于科学计算,通常需要更多的控制。为了加以区分 numpy 在这些类型名称末尾都加了“_”。类型…

【ESP32+freeRTOS学习笔记-(九)事件组】

目录1、概述2、事件组的特性2.1 事件组、事件标志和事件位2.2 事件组位长的设置2.3 多任务访问3、使用事件组管理事件3.1 xEventGroupCreate()3.2 xEventGroupSetBits()3.3 xEventGroupGetBits()3.4 xEventGroupWaitBits()3.5 示例4、使用事件组同步任务4.1 xEventGroupSync()4…

MobaXterm安装与使用

MobaXterm安装与使用 我们首先进入MobaXterm官网,其提供了收费版和免费版,我们使用免费版即可 随后便是安装过程了,很简单。解压后运行该文件一路next即可。 安装完成后我们便可以使用了点击session 选择SSH连接方式,输入服务器…

vue项目——获取指定日期是周几和第几周的信息——表格展示

最近在写后台管理系统,遇到以下的要求,就是要展示 年月日和周几和第几周的情况。 下面记录一下用到的函数: 1.跟据日期获取第几周 //根据日期获取第几周 getWeek(dateTime) {let temptTime new Date(dateTime);//周几let weekday temptT…

浏览器用一行JS代码导出cookies.txt,Python的requests库导入cookies格式化为字典格式

在Python进行爬虫时,如果仅使用requests库打开某个网页,requests的session.cookies保存的cookies信息少得可怜,有时cookies甚至是空白!但浏览器里打开同一个网页,cookies信息非常详尽,比如浏览器的cookies保…