更新docker 容器时,提前换后端jar 包,为什么会存在异常

我们现场更新时,通常都是提前将后端jar 包替换了,然后到了更新的时间,只需要更新相关的前端文件和修改各种配置,就行了。

但是最近一次更新操作中,忽然发现,提前更新后端包,会存在依赖丢失问题????

文章目录

    • 结论
    • docker 容器的挂载逻辑
      • 一、挂载类型与实时性
      • 二、实时同步的实现机制
      • 三、例外情况与注意事项
      • 四、验证实时性的方法
    • java -jar 是干什么
      • 一、JAR包运行的本质
      • 二、实际实现流程
      • 三、常见问题与底层机制
      • 四、扩展:调试与优化
      • 总结
    • java 启动时会将jar 包中那些内容导入内存中
      • 一、类文件与元数据
      • 二、静态资源与配置文件
      • 三、类加载机制的关键阶段
      • 四、动态加载与内存管理
      • 五、优化与注意事项

结论

就是不能换(因为判断修改是否影响的逻辑比较复杂),之前认为能换,是认为jar 包线上系统不会重新调用相关内容,结合下述相关知识,可以知道,在java 服务运行时,至少有动态加载这种情况时,(开发是动静分离的,静态资源应该可以忽略)服务会重新搜索jar 包的相关.class 文件,重新生成类对象。

docker 容器的挂载逻辑

Docker 容器的挂载逻辑是实时同步的,其数据交互机制依赖于宿主机的文件系统通知功能。具体逻辑如下:


一、挂载类型与实时性

  1. 绑定挂载(Bind Mount)
    将宿主机目录直接映射到容器内,修改任一端(宿主机或容器)的文件会立即同步到另一端。这是最常用的实时挂载方式,适用于开发环境中的代码热更新场景12。
  2. 卷挂载(Volume Mount)
    由 Docker 管理的持久化存储卷,数据存储在宿主机特定路径(如 <font style="color:rgba(0, 0, 0, 0.9);">/var/lib/docker/volumes</font>)。与绑定挂载类似,修改实时同步,但更适合生产环境的数据持久化需求49。
  3. 临时文件系统(tmpfs)
    数据仅存储在内存中,容器重启后丢失。虽然数据不持久化,但容器运行期间的读写操作也是实时生效的25。

二、实时同步的实现机制

  • 文件系统层映射
    Docker 通过 Linux 的命名空间(Namespace)和控制组(cgroup)技术,将宿主机的文件系统路径直接映射到容器内部,底层依赖宿主机文件系统的 inotify 机制实现实时通知911。
  • 写时复制(Copy-on-Write)优化
    仅当文件被修改时触发同步,未修改的文件仍共享宿主机的原始数据层,避免不必要的性能开销7。

三、例外情况与注意事项

  1. 网络文件系统(NFS)延迟
    若挂载的是远程存储(如 NFS),同步时效性受网络环境影响,可能出现短暂延迟12。
  2. 容器内应用缓存
    某些应用程序(如数据库)可能缓存数据到内存,导致文件系统修改不会立即体现在应用层,需手动刷新或重启服务38。
  3. 权限问题
    若宿主机与容器内用户权限不匹配(如 UID/GID 不一致),可能导致挂载目录无法实时写入610。

四、验证实时性的方法

可通过以下命令快速测试:

bash# 宿主机操作 
echo "test" > /host/path/file.txt  # 进入容器查看 
docker exec -it container_name cat /container/path/file.txt

若容器内能立即看到更新内容,则证明挂载实时生效12。


总结:Docker 的挂载机制默认是实时同步的,但需结合具体挂载类型和应用场景综合判断。对于关键业务,建议通过日志或主动监控进一步验证数据一致性

java -jar 是干什么

通过<font style="color:rgba(0, 0, 0, 0.9);">java -jar</font>命令运行Java JAR包的本质是通过JVM加载JAR文件中的主类并执行其**<font style="color:rgba(0, 0, 0, 0.9);">main()</font>**方法,其实现流程可分为以下核心步骤:


一、JAR包运行的本质

  1. JAR文件结构
    JAR包本质是ZIP格式的压缩文件,包含:
    • 编译后的<font style="color:rgba(0, 0, 0, 0.9);">.class</font>文件;
    • 资源文件(如图片、配置文件);
    • <font style="color:rgba(0, 0, 0, 0.9);">META-INF/MANIFEST.MF</font>清单文件(指定主类、依赖路径等元数据)18。
  2. 清单文件的关键作用
    <font style="color:rgba(0, 0, 0, 0.9);">MANIFEST.MF</font>中的<font style="color:rgba(0, 0, 0, 0.9);">Main-Class</font>属性决定了入口类,JVM通过此属性定位并调用指定类的<font style="color:rgba(0, 0, 0, 0.9);">main()</font>方法。若未正确配置此属性,会报错“找不到主清单属性”14。
  3. 类加载机制
    JVM将JAR包视为一个类路径(Classpath),通过内置的<font style="color:rgba(0, 0, 0, 0.9);">JarClassLoader</font>加载其中的类。若依赖其他JAR,需通过<font style="color:rgba(0, 0, 0, 0.9);">-cp</font>参数显式指定路径79。

二、实际实现流程

  1. 环境检查
    • 检查系统是否安装兼容版本的JRE/JDK(通过<font style="color:rgba(0, 0, 0, 0.9);">java -version</font>验证)18。
    • 确保<font style="color:rgba(0, 0, 0, 0.9);">JAVA_HOME</font>环境变量指向正确的JDK路径19。
  2. 命令行解析
    • <font style="color:rgba(0, 0, 0, 0.9);">java -jar</font>命令触发JVM启动,并解析参数:

java -jar yourfile.jar  [args...]
- <font style="color:rgba(0, 0, 0, 0.9);">若需指定堆内存或垃圾回收策略,可添加</font>`<font style="color:rgba(0, 0, 0, 0.9);">-Xmx</font>`<font style="color:rgba(0, 0, 0, 0.9);">、</font>`<font style="color:rgba(0, 0, 0, 0.9);">-XX:+UseG1GC</font>`<font style="color:rgba(0, 0, 0, 0.9);">等参数</font>[<font style="color:rgb(22, 119, 255);">1</font>](https://docs.pingcode.com/baike/254964)[<font style="color:rgb(22, 119, 255);">13</font>](https://blog.csdn.net/AttleeTao/article/details/104149794)<font style="color:rgba(0, 0, 0, 0.9);">。</font>
  1. JAR包加载与清单读取
    • JVM解压JAR包至临时目录(或直接从内存读取)。
    • 解析<font style="color:rgba(0, 0, 0, 0.9);">META-INF/MANIFEST.MF</font>文件,提取<font style="color:rgba(0, 0, 0, 0.9);">Main-Class</font><font style="color:rgba(0, 0, 0, 0.9);">Class-Path</font>(若存在依赖库)48。
  2. 主类加载与执行
    • 通过反射机制加载<font style="color:rgba(0, 0, 0, 0.9);">Main-Class</font>指定的类。
    • 调用该类的<font style="color:rgba(0, 0, 0, 0.9);">public static void main(String[] args)</font>方法,传递命令行参数<font style="color:rgba(0, 0, 0, 0.9);">args</font>913。
  3. 依赖处理
    • 内嵌依赖:若使用Fat JAR(包含所有依赖),直接加载内部类。
    • 外部依赖:通过<font style="color:rgba(0, 0, 0, 0.9);">-cp</font>参数或<font style="color:rgba(0, 0, 0, 0.9);">MANIFEST.MF</font>中的<font style="color:rgba(0, 0, 0, 0.9);">Class-Path</font>指定外部JAR路径79。

三、常见问题与底层机制

  1. 权限问题
    Linux系统需确保JAR文件有执行权限(<font style="color:rgba(0, 0, 0, 0.9);">chmod +x yourfile.jar</font> )813。
  2. 版本兼容性
    JVM版本需与编译JAR包的JDK版本匹配,否则可能报错<font style="color:rgba(0, 0, 0, 0.9);">UnsupportedClassVersionError</font>17。
  3. 进程管理
    • 前台运行:直接执行<font style="color:rgba(0, 0, 0, 0.9);">java -jar</font>,关闭终端则进程终止。
    • 后台运行:使用<font style="color:rgba(0, 0, 0, 0.9);">nohup java -jar &</font><font style="color:rgba(0, 0, 0, 0.9);">javaw</font>(Windows)实现守护进程313。

四、扩展:调试与优化

  1. 调试命令
    添加<font style="color:rgba(0, 0, 0, 0.9);">-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</font>启用远程调试3。
  2. 性能优化
    • 通过<font style="color:rgba(0, 0, 0, 0.9);">-Xms</font><font style="color:rgba(0, 0, 0, 0.9);">-Xmx</font>调整堆内存大小。
    • 使用<font style="color:rgba(0, 0, 0, 0.9);">-XX:+HeapDumpOnOutOfMemoryError</font>生成内存溢出快照113。

总结

运行JAR包的本质是JVM根据清单文件定位入口类并执行其主方法,而流程涵盖环境检查、文件解析、类加载到程序执行的完整链路。理解这一机制有助于解决依赖冲突、版本不兼容等问题,并优化部署流程。

java 启动时会将jar 包中那些内容导入内存中

ava 启动时加载 JAR 包中的内容到内存的过程主要涉及类加载机制和资源管理机制。以下是具体会导入内存的内容及加载逻辑:


一、类文件与元数据

  1. Class 文件
    JAR 包中的 <font style="color:rgba(0, 0, 0, 0.9);">.class</font> 文件会被类加载器按需加载到内存中,并生成对应的 <font style="color:rgba(0, 0, 0, 0.9);">java.lang.Class</font> 对象。
    • 加载顺序:主类及其直接依赖优先加载,其他类延迟加载(例如通过 <font style="color:rgba(0, 0, 0, 0.9);">new</font> 或反射调用时触发加载)12。
    • 存储区域:类元信息(如方法、字段结构)存储在方法区(JDK8+ 为元空间 Metaspace),静态变量存储在堆内存中的 Class 对象中。
  2. MANIFEST.MF 文件
    该文件位于 <font style="color:rgba(0, 0, 0, 0.9);">META-INF</font> 目录下,包含 JAR 包的元数据(如主类定义、类路径等)。启动时会解析此文件以确定入口类和依赖关系812。

二、静态资源与配置文件

  1. 配置文件
    <font style="color:rgba(0, 0, 0, 0.9);">application.properties</font><font style="color:rgba(0, 0, 0, 0.9);">XML</font> 等文件,通过 <font style="color:rgba(0, 0, 0, 0.9);">ClassLoader.getResourceAsStream()</font> 读取到内存中。但并非所有文件都会被自动加载,需显式调用资源读取代码才会导入11。
    • 示例:Spring 项目启动时,通过 <font style="color:rgba(0, 0, 0, 0.9);">FileSystemXmlApplicationContext</font> 加载外部配置文件11。
  2. 静态资源
    图片、模板等非类文件通常通过类路径访问,按需加载到内存。例如:
java复制
InputStream is = MyClass.class.getResourceAsStream("/images/logo.png");

三、类加载机制的关键阶段

  1. 加载(Loading)
    <font style="color:rgba(0, 0, 0, 0.9);">.class</font> 文件读入内存,生成 <font style="color:rgba(0, 0, 0, 0.9);">Class</font> 对象。类加载器层级包括:
    • Bootstrap ClassLoader:加载核心 JDK 类(如 <font style="color:rgba(0, 0, 0, 0.9);">java.lang.*</font> )。
    • Extension ClassLoader:加载 <font style="color:rgba(0, 0, 0, 0.9);">jre/lib/ext</font> 目录下的扩展 JAR。
    • System ClassLoader:加载应用类路径(含用户 JAR 包)12。
  2. 连接(Linking)
    • 验证:检查字节码是否符合 JVM 规范。
    • 准备:为静态变量分配内存并赋默认值(如 <font style="color:rgba(0, 0, 0, 0.9);">int</font> 初始化为 0)。
    • 解析:将符号引用转为直接引用(如方法实际内存地址)12。
  3. 初始化(Initialization)
    执行静态代码块和显式静态变量赋值(如 <font style="color:rgba(0, 0, 0, 0.9);">static int a = 5;</font>)。

四、动态加载与内存管理

  1. 动态加载
    可通过 <font style="color:rgba(0, 0, 0, 0.9);">URLClassLoader</font> 在运行时动态加载外部 JAR 包中的类(需调用 <font style="color:rgba(0, 0, 0, 0.9);">addURL()</font> 方法)7。例如:
java复制
URLClassLoader loader = new URLClassLoader(new URL[]{new File("lib/external.jar").toURI().toURL()}); 
Class<?> clazz = loader.loadClass("com.example.ExternalClass");
  1. 内存区域
    • 堆(Heap):存储对象实例和数组。
    • 方法区(Metaspace):存储类元信息、常量池。
    • 栈(Stack):存储线程方法调用的局部变量和操作数612。

五、优化与注意事项

  1. 内存参数
    可通过 JVM 参数控制内存分配:
bashjava -Xms512m -Xmx1024m -jar app.jar   # 设置堆内存初始和最大值[6]()
  1. 资源释放
    未使用的类可能被垃圾回收(需满足类卸载条件),但 Metaspace 默认不会主动释放,需配置 <font style="color:rgba(0, 0, 0, 0.9);">-XX:MetaspaceSize</font><font style="color:rgba(0, 0, 0, 0.9);">-XX:MaxMetaspaceSize</font>

总结:Java 启动时主要加载 JAR 包中的类文件、静态资源和配置文件到内存,具体内容取决于代码的显式调用和类依赖关系。类加载器层级和 JVM 内存模型共同决定了资源在内存中的分布与管理。

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

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

相关文章

LoRA 模型微调框架核心原理及实现步骤

LoRA&#xff08;Low-Rank Adaptation&#xff09;模型微调框架通过低秩矩阵分解原理&#xff0c;实现了对大型预训练模型的高效微调。其核心原理是&#xff1a;在冻结预训练模型权重的基础上&#xff0c;向特定层注入可训练的低秩矩阵&#xff0c;以极少量参数&#xff08;通常…

XHR.readyState详解

XHR.readyState详解 引言 XHR.readyState是XMLHttpRequest对象的一个属性,它反映了当前请求的状态。在Ajax编程中,正确理解和使用XHR.readyState对于调试和确保异步请求的正确执行至关重要。本文将详细介绍XHR.readyState的属性值、含义以及在Ajax请求中的具体应用。 XHR.…

MySQL8.4 InnoDB Cluster高可用集群使用指南

简介 高可用方案 Orchestrator&#xff1a; 可视化 Web 界面管理 MySQL 拓扑结构&#xff0c;并且兼容多种复制架构&#xff08;异步、半同步、GTID&#xff09;&#xff0c;提供自动和手动的故障转移。但是8.0.21后 MySQL 更新了主从复制相关命令&#xff0c;Orchestrator无…

扩散模型总结

目录 定义与原理 发展历程 正向扩散过程 反向扩散过程 噪声预测网络 离散时间模型 连续时间模型 条件扩散模型 生成质量 训练稳定性 采样灵活性 图像生成 音频合成 文本生成 计算效率 模型复杂度 定义与原理 扩散模型是一种新型的生成模型,其核心原理源于热力…

【Java】Java核心知识点与相应面试技巧(七)——类与对象(二)

Java 类与对象篇 1.上期面试题解析&#xff1a; 上文链接&#xff1a;https://blog.csdn.net/weixin_73492487/article/details/146607026 创建对象时的内存分配过程&#xff1f; ① 加载类 ② 堆内存分配空间 ③ 默认初始化 ④ 显式初始化 ⑤ 构造器执行 this和super能否同时…

笔记:遇见未来——6G协同创新技术研讨会

https://www.cww.net.cn/article?id564308 研讨会由中国移动研究院首席科学家易芝玲博士主持。来自清华大学-中国移动联合研究院、北京邮电大学-中国移动研究院联合创新中心、东南大学-中国移动研究院联合创新中心、中关村泛联移动通信技术创新应用研究院等合作载体的知名教授…

Python Cookbook-4.14 反转字典

任务 给定一个字典&#xff0c;此字典将不同的键映射到不同的值。而你想创建一个反转的字典&#xff0c;将各个值反映射到键。 解决方案 可以创建一个函数&#xff0c;此函数传递一个列表推导作为dict的参数以创建需要的字典。 def invert_dict(d):return dict([(v,k) for …

深度学习在测距模型中的应用

一、单目视觉测距和双目视觉测距简介 1、单目视觉测距 模型&#xff1a;深度估计&#xff08;Depth Estimation&#xff09; 原理&#xff1a;通过深度学习模型&#xff08;如MonoDepth2、MiDaS&#xff09;或传统的计算机视觉方法&#xff08;如单目相机结合物体大小推断&am…

Linux Mem -- Slub内存分配器的几点疑问及解答

目录 1 怎样通过object地址获取其对应的struct slab&#xff1f; 2 struct page、struct folio和struct slab类型之间转换&#xff0c;怎么保证内部关键数据的传递&#xff1f; 3 怎样判断一个内存空间是属于slab、page管理&#xff1f; 4 struct page 结构中 __mapcou…

pip install cryptacular卡住,卡在downloading阶段

笔者安装pip install cryptacular卡在downloading阶段&#xff0c;但不知道为何 Collecting cryptacularCreated temporary directory: /tmp/pip-unpack-qfbl8f08http://10.170.22.41:8082 "GET http://repo.huaweicloud.com/repository/pypi/packages/42/69/34d478310d6…

Lag-Llama时间序列模型简单实现数据预测

前言&#xff1a; 最近在大模型预测&#xff0c;简单了解了lag-llama开源项目&#xff0c;网上也有很多讲解原理的&#xff0c;这里就将如何快速上手使用说一下&#xff0c;只懂得一点点皮毛&#xff0c;有错误的地方欢迎大佬指出。 简单介绍&#xff1a; Lag-Llama 是一个开…

Plastiform复制胶泥:高精度表面复制与测量的高效工具

在工业制造和质量检测领域&#xff0c;表面复制和测量是确保产品质量的关键环节。Plastiform复制胶泥作为一种创新材料&#xff0c;凭借其出色的性能和多样化的应用&#xff0c;为用户提供了可靠的解决方案。它能够快速捕捉复杂表面的细节&#xff0c;确保测量结果的准确性&…

AI大模型、机器学习以及AI Agent开源社区和博客

以下梳理了适合学习 AI大模型、机器学习、AI Agent和多模态技术 的英文网站、社区、官网和博客&#xff0c;按类别分类整理&#xff1a; 一、官方网站与开源平台 1. AI大模型 (Large Language Models) • OpenAI • 官网: openai.com • 内容: GPT系列模型文档、研究论文、AP…

python 上下文管理器with

with 上下文管理器 上下文管理器示例如下&#xff1a;若想不使用with关键字 上下文管理器 任何实现了 enter() 和 exit() 方法的对象都可称之为上下文管理器&#xff0c;上下文管理器对象可以使用 with 关键字。 必须同时具有__enter__和__exit__&#xff0c;就可以使用with语句…

买卖股票的最佳时机(121)

121. 买卖股票的最佳时机 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int cur_min prices[0];int max_profit 0;for (int i 1; i < prices.size(); i) {if (prices[i] > cur…

CesiumJS 本地数据瓦片加载南北两极出现圆点问题

const imageryProvider new UrlTemplateImageryProvider({url: "/gisimg/{z}/{x}/{reverseY}.png",minimumLevel: 0,maximumLevel: 19})上面这段代码是加载本地切片&#xff0c;但是有个致命问题就是会出现南北两极显示蓝色圆点 解决方案&#xff1a; 加上这句话&am…

Linux编译器gcc/g++使用完全指南:从编译原理到动静态链接

一、gcc/g基础认知 在Linux开发环境中&#xff0c;gcc和g是我们最常用的编译器工具&#xff1a; gcc&#xff1a;GNU C Compiler&#xff0c;专门用于编译C语言程序g&#xff1a;GNU C Compiler&#xff0c;用于编译C程序&#xff08;也可编译C语言&#xff09; &#x1f4cc…

Vue学习笔记集--computed

computed 在 Vue 3 的 Composition API 中&#xff0c;computed 用于定义响应式计算属性 它的核心特性是自动追踪依赖、缓存计算结果&#xff08;依赖未变化时不会重新计算&#xff09; 基本用法 1. 定义只读计算属性 import { ref, computed } from vue;const count ref(…

飞致云荣获“Alibaba Cloud Linux最佳AI镜像服务商”称号

2025年3月24日&#xff0c;阿里云云市场联合龙蜥社区发布“2024年度Alibaba Cloud Linux最佳AI镜像服务商”评选结果。 经过主办方的严格考量&#xff0c;飞致云&#xff08;即杭州飞致云信息科技有限公司&#xff09;凭借旗下MaxKB开源知识库问答系统、1Panel开源面板、Halo开…

Vue如何利用Postman和Axios制作小米商城购物车----简版

实现功能&#xff1a;全选、单选、购物数量显示、合计价格显示 实现效果如下&#xff1a; 思路&#xff1a; 1.数据要利用写在Postman里面&#xff0c;通过地址来调用Postman里面的数据。 2.写完数据后&#xff0c;给写的数据一个名字&#xff0c;然后加上一个空数组&#xf…