更新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.rhkb.cn/news/41185.html

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

相关文章

超详细docker部署搭建私有仓库harbor

一、安装docker 确保你的服务器上已经安装了 Docker 如果没有安装&#xff0c;按以下方法安装 yum install -y yum-utils yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo yum install docker-ce docker-ce-cli containerd.io 启动d…

541. 反转字符串 II

541. 反转字符串 IIhttps://leetcode.cn/problems/reverse-string-ii/ 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xff0c;就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个&#xff0c;则将剩余字符全部反转。…

力扣HOT100之普通数组:53. 最大子数组和

这道题目我用贪心做的&#xff0c;感觉用贪心的思路比较简单&#xff0c;以后要是面试碰到这道题就直接用贪心好了&#xff0c;这道题用贪心的核心思想就是不断将数组元素i加入总和sum&#xff0c;如果sum比当前维护的最大值result更大&#xff0c;说明当前遍历到的i是正数&…

muduo库的思路梳理

前言 对于muduo库源码的剖析我发现还是有些混乱的&#xff0c;所以这里再次梳理一下muduo网络库争取可以简单明了 首先对于muduo库来说&#xff0c;不能想的得太过于复杂&#xff0c;它无非就是一个线程池加上epoll组成的网络库 这里我们从用的角度出发理解muoduo网络库 #inc…

【C语言系列】数据在内存中存储

数据在内存中存储 一、整数在内存中的存储二、大小端字节序和字节序判断2.1什么是大小端&#xff1f;2.2练习2.2.1练习12.2.2练习22.2.3练习32.2.4练习42.2.5练习52.2.6练习6 三、浮点数在内存中的存储3.1练习3.2浮点数的存储3.2.1 浮点数存的过程3.2.2 浮点数取的过程 3.3题目…

C++学习之网盘项目单例模式

目录 1.知识点概述 2.单例介绍 3.单例饿汉模式 4.饿汉模式四个版本 5.单例类的使用 6.关于token的作用和存储 7.样式表使用方法 8.qss文件中选择器介绍 9.qss文件样式讲解和测试 10.qss美化登录界面补充 11.QHTTPMULTIPART类的使用 12.文件上传协议 13.文件上传协议…

多模态自动驾驶混合渲染HRMAD:将NeRF和3DGS进行感知验证和端到端AD测试

基于3DGS和NeRF的三维重建技术在过去的一年中取得了快速的进步&#xff0c;动态模型也变得越来越普遍&#xff0c;然而这些模型仅限于处理原始轨迹域内的对象。 HRMAD作为一种混合方案&#xff0c;将传统的基于网格的动态三维神经重建和物理渲染优势结合&#xff0c;支持在任意…

质检LIMS系统在食品生产加工企业的应用 如何保证食品生产企业的安全

在食品生产加工领域&#xff0c;质量安全是贯穿全产业链的生命线。随着《食品安全法》对全过程追溯要求的深化&#xff0c;传统实验室管理模式已难以满足高效、精准的质量管控需求。质检实验室信息管理系统&#xff08;LIMS&#xff09;作为数字化升级的核心工具&#xff0c;正…

树莓派超全系列文档--(8)RaspberryOS实用程序

RaspberryOS实用程序 实用程序kmsprintvclogvcgencmdvcosversionget_throttledmeasure_tempmeasure_clock [clock]measure_volts [block]otp_dumpget_config [configuration item|int|str]get_mem typecodec_enabled [type]mem_oommem_reloc_statsread_ring_osc 文章来源&#…

解锁DeepSeek潜能:Docker+Ollama打造本地大模型部署新范式

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《深度探秘&#xff1a;AI界的007》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是Docker 2、什么是Ollama 二、准备工作 1、操…

文件上传绕过的小点总结(6)

14.文件上传&#xff08;文件包含漏洞&#xff09;二次渲染 很多服务器为了防止代码嵌入图片&#xff0c;通常会将上传的图片进行重新生成处理&#xff0c;包括文件格式转换等等&#xff0c;嵌入的恶意代码很容易被改掉。于是产生了二次渲染&#xff0c;二次渲染的原理就是找到…

x-cmd install | Wuzz - Web 开发与安全测试利器,交互式 HTTP 工具

目录 安装配置快捷键上下文相关搜索待办事项 在 Web 开发和安全测试中&#xff0c;我们经常需要检查和修改 HTTP 请求。浏览器自带的开发者工具虽然好用&#xff0c;但复制出来的 cURL 命令冗长且难以编辑。今天要介绍的是 Wuzz&#xff0c;一款交互式命令行 HTTP 工具&#xf…

python --face_recognition(人脸识别,检测,特征提取,绘制鼻子,眼睛,嘴巴,眉毛)/活体检测

dlib 安装方法 之前博文 https://blog.csdn.net/weixin_44634704/article/details/141332644 环境: python3.8 opencv-python4.11.0.86 face_recognition1.3.0 dlib19.24.6人脸检测 import cv2 import face_recognition# 读取人脸图片 img cv2.imread(r"C:\Users\123\…

搭建k8s集群的可观测体系(log和metric)(已踩完坑)

Loki是日志聚合系统,属于云原生技术,由Grafana Labs开发。它专注于轻量级和高效的日志管理,特别是适合Kubernetes环境。而Prometheus-operator则是用来管理Prometheus监控系统的,简化部署和配置,处理监控数据,尤其是指标(metrics)的收集和告警。 本片文档踩坑结束,使用…

Mybatis配置文件解析(详细)

引言 在了解Mybatis如何帮助客户进行数据的存取后&#xff0c;便对Mybatis的配置文件起了兴趣&#xff0c;在查阅官方文档后&#xff0c;总结了平时能用到的配置&#xff0c;希望能对大家有帮助 1.核心配置文件 主要是指Mybatis-config.xml中 其包含了会深深影响Mybatis行为…

技术迭代、流量困境与营销突破:基于开源AI大模型与S2B2C模式的创新路径研究

摘要&#xff1a;在技术指数级迭代与流量红利消退的双重背景下&#xff0c;营销领域面临边际效应递减与竞争升级的双重挑战。本文基于"开源AI大模型""AI智能名片""S2B2C商城""小程序源码"等创新工具&#xff0c;探讨营销范式转型的路径…

针对stm32F103C8t6芯片调节USB串口的经验

1、首先这是自己手搓的板子,对于之前一直没有了解过USB这方面,则这个针对USB部分没有设计上拉电阻,造成不管怎么调节PC端都没有反应。 图一 这个没有添加1.5K电阻 这个D+位置应该再接一个1.5KR的电阻如图2所示 图2 这样调节的话PC端就可以识别到USB串口,但是这是串口还是会…

数据库和安装配置MySQL笔记(2)

1. 什么是数据库&#xff1f; 数据库&#xff08;Database&#xff09;是按照数据结构来组织、存储和管理数据的仓库。它通过系统化的方法&#xff0c;帮助用户高效地存储、检索和管理数据。 2. 常见数据库类型 关系型数据库&#xff08;如 MySQL、PostgreSQL、Oracle&#…

mysql增、删、改和单表查询多表查询

一、四大名著表t_hero的相关操作&#xff1a; 1.进入并创建db_ck数据库&#xff1a; create database if not exists db_ck; show databases; use db_ck;2.创建四大名著表t_hero并且插入一些数据&#xff1a; 创建t_hero表&#xff1a; create table t_hero ( id int, hero…

springboot整合couchbase(集群)

springboot整合couchbase 1、Couchbase1.1、介绍1.2、Bucket1.3、Couchbase SDK 2、(key,value)写入couchbase集群2.1、总体图2.2、依赖2.3、CouchbaseConfig 配置文件2.4、代码使用 1、Couchbase 1.1、介绍 1.2、Bucket 在 Couchbase 中&#xff0c;bucket 是一个重要的概念…