发布时间:2025-06-09
浏览次数:0
前言
近期,我利用Cloud平台搭建了一个微服务架构的工程,但在部署过程中遭遇了挑战:内存资源不足。该工程包含7个微服务组件,由于我仅拥有一台配置为2核4G的阿里云服务器,因此不得不将所有微服务部署在同一台服务器上。为此,我采用了自制的fat jar镜像进行部署,每个微服务在未进行任何JVM参数调整的前提下,其内存占用大约为500M。
微服务架构的特性决定了必须进行部署,例如nacos;此外,还采用了redis、elk等工具(其中mysql为阿里云购买),仅这些应用的运行就耗费了2G以上的内存;在部署了4个微服务之后,剩余的1G多内存空间便告罄,因此,我们开始对应用的内存进行初步的优化工作。
添加JVM参数优化内存大小
JVM在启动时分配的内存大小由参数-Xms设定,其默认值通常为物理内存的六十四分之一。
-Xms128m
JVM所能分配的最大内存容量由参数-Xmx设定,其默认值通常为物理内存的四分之一。
-Xmx128m
该规定明确了每个线程的虚拟机栈和堆栈容量,通常情况下,256k的配置是足够的,这样的设置将直接决定该进程能够支持的最大并发线程数量。
-Xss256k
# 指定并行GC线程的数量,一般最好和CPU核心数量相当
-XX:ParallelGCThreads=2
当可用堆内存低于40%时,JVM会自动扩充堆内存至-Xmx设定的上限;而若剩余堆内存超过70%,JVM则会相应地缩减堆内存至-Xms规定下的下限。
因此,服务器通常将-Xms和-Xmx参数设置为相同值,以此防止在每次垃圾回收后对堆内存大小进行调整。堆内存中的对象是由一种名为垃圾回收器的自动内存管理机制进行回收的。
在CPU数量不足8台的情况下,该参数的数值等同于CPU的数量;以我的2核CPU服务器为例,这一参数可以忽略不计。完成配置并启动服务后,观察到内存容量确实有所减少,从最初的500M降至100至200M,但这并非我所期待的结果;我期望内存能够降至几十M的水平。
通过在网络上广泛搜集相关资料,我发现这项新技术能够满足我的需求。然而,需要注意的是,这项技术目前正经历快速更新,变化频繁,因此建议仅用于个人学习目的,不宜应用于实际生产。
项目使用 后:
应用启动速度特别快,毫秒级别
运行时内存占用更少,官方展示的包含Boot、MVC等组件的镜像文件体积仅为50MB。
为了实现预期的目标,需要付出构建周期较长的代价——即便是简单的“Hello World”项目,构建过程也可能耗时两分钟,而这主要取决于计算机的配置,我的电脑大概需要这个时间。
是什么
简而言之就是为了提高Java在云原生的竞争力(个人理解)。
以下内容摘抄自上 的自述文件:
为了支持原生映像编译器将应用程序编译成原生可执行文件intellij idea golang plugin,同时提供一种通常打包于轻量级容器中的原生部署选择,我们提供了beta版本的辅助。实际上,我们的目标是确保在这个新平台上,几乎无需修改的Boot应用程序也能得到支持。
以下内容摘抄自其他博客:
近年来,“原生”这一概念在云计算、边缘计算等行业中广泛流传,而备受青睐的原生语言则始终是Rust等不依赖特定运行环境的编程语言。Java得益于上世纪流行的“一次编译,到处执行”的理念而广受欢迎,然而,也正是这一特性使得Java程序难以摆脱JVM运行环境的束缚,从而降低了其在原生程序中的受欢迎程度。在当前云原生技术广泛应用的背景下,Java应用程序由于JVM的臃肿特性,相较于其他编程语言显得尤为庞大。众多技术高手纷纷探索,寻求多种途径以使Java变得更加“原生”。
实战
本次实战相关的环境信息如下:
从官方文档得知(上图)
应用此软件时,需确保采用 Java 11 或 Java 17 进行编译。
构建 Boot 原生应用程序有两种主要方法:
使用 Boot 支持生成包含本机可执行文件的轻量级容器。
使用 原生镜像 Maven 插件支持生成原生可执行文件。
历经多次尝试与错误,我最终在本机上顺利实现了方法一和方法二的运用。简言之:
在步骤3之后,我们能够借助-boot-maven-插件来构建镜像,通过执行mvn -boot:build-image命令并利用其API来构建Boot原生应用程序,一旦操作顺利完成,便会自动生成一个镜像,之后只需运行该镜像即可,无需我们额外编写代码,所有相关参数的配置都已在pom.xml文件中进行设定(位于该插件的标签下,与-maven-的配置相近)。
无需安装,但需先行安装特定软件,完成安装后,通过运行mvn命令,即可生成一个可执行的文件(.exe),随后直接运行该文件即可。
主要区别如下
1 环境依赖不同2 执行的maven命令不同
鉴于各个微服务采用部署而非exe文件的形式,故而方法一恰巧满足了个人需求;因此,在后续内容中,将以Boot模式来构建Boot原生应用。
1 安装Graal VM(-ce---amd64)
官方下载地址:
https://www..org//
2 配置环境变量
关于方法1,从那三幅图来看,似乎仅需调整设置即可。若希望一蹴而就,建议三个都进行配置,之后可自行进行测试。此外,还可以进一步探索。
检验是否安装成功
3 安装-image
打开新的cmd,输入以下命令,等待安装
gu install native-image
我尝试的这一步没有成功,要解决这个问题,需要手动从网络上下载'image'文件,接着进行解压和安装操作。
请勿访问该网址,其中包含的路径指向一个名为“vm-21.3.0”的文件,该文件是针对amd64架构的,版本号为21.3.0,属于图像处理工具的JAR包。
jar用也是可以解压的,解压后如下
在bin目录下打开cmd,输入以下命令,等待安装
$ gu install -L native-image*
4 安装 for
具体步骤略,按照官方文档操作即可:
https://docs..com////
5 配置pom.xml
前面都是准备工作,这一步开始才是重点
首先快速创建一个 Boot项目,我命名为-
完整的pom如下
<project xmlns=该链接指向的是Apache Maven项目的版本4.0.0的POM文件规范。 xmlns:xsi=该网址指向的是"http://www.w3.org/2001/XMLSchema-instance",这是一个与XML模式实例相关的标准链接。
xsi:schemaLocation=请访问"http://maven.apache.org/POM/4.0.0",同时,也请查阅"https://maven.apache.org/xsd/maven-4.0.0.xsd"。>
<modelVersion>4.0.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.6.2version>
<relativePath/>
parent>
<groupId>ltd.pcddgroupId>
<artifactId>spring-nativeartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>spring-nativename>
<description>spring-nativedescription>
<properties>
<java.version>11java.version>
<repackage.classifier/>
<spring-native.version>0.11.1spring-native.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>Spring框架下的实验性模块groupId>
<artifactId>spring-nativeartifactId>
<version>${spring-native.version}version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.experimentalgroupId>
<artifactId>spring-aot-maven-pluginartifactId>
<version>0.11.1version>
<executions>
<execution>
<id>generateid>
<goals>
<goal>generategoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder:tinybuilder>
<env>
<BP_NATIVE_IMAGE>trueBP_NATIVE_IMAGE>
env>
image>
configuration>
plugin>
plugins>
build>
<repositories>
<repository>
<id>spring-releaseid>
<name>Spring releasename>
<url>请访问Spring的发布仓库,链接为https://repo.spring.io/release。url>
repository>
repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-releaseid>
<name>Spring releasename>
<url>https://repo.spring.io/releaseurl>
pluginRepository>
pluginRepositories>
project>
本文所涉及的是版本11.1,与之相匹配的Boot版本应为2.6.2。这仅仅是一个基础的配置示例,而在实际的开发过程中,我们还需在-boot-maven-插件标签内设置众多额外的参数。
对于远程地址、证书路径、JVM优化参数、配置文件设定、镜像名称、端口以及仓库地址等信息的指定,最有效的途径是查阅-boot-maven-的官方指南。以下以配置JVM参数为例。
通过官方文档得知只需要在标签下配置即可,例如
<image>
<builder>paketobuildpacks/builder:tinybuilder>
<env>
<BP_NATIVE_IMAGE>trueBP_NATIVE_IMAGE>
<BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> BPE_DELIM_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Xms128mBPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Xmx128mBPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-Xss256kBPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:ParallelGCThreads=2BPE_APPEND_JAVA_TOOL_OPTIONS>
<BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+PrintGCDetailsBPE_APPEND_JAVA_TOOL_OPTIONS>
env>
image>
其他的配置参数还有很多。扩展:
官方文档:
请勿访问该链接,以避免进入未经验证的文档页面,特别是当它指向的是关于构建镜像的详细说明时。
6 执行maven命令
mvn clean
mvn '-Dmaven.test.skip=true' spring-boot:build-image
完成依赖文件的下载之后,机器的散热风扇随即响起嗡嗡声,通过任务管理器查看,CPU的使用率高达100%,内存占用急剧上升,并最终保持在90%以上的水平。
构建成功
7 创建并运行容器
查看所有镜像
-就是构建的镜像
创建并运行容器
在查阅日志过程中,我发现应用已经顺利启动,启动过程极为迅速,耗时仅短短数秒,即59毫秒,这确实验证了启动速度达到毫秒级的说法。
成功调用接口
在 查看占用内存,仅28M左右。
不使用 启动应用
启动耗时3s,占用内存高达511M,高下立判。
文章仅供参考,建议结合 官方最新文档学习。
严禁对文档进行任何形式的篡改,确保链接指向的索引页面保持原样,不得进行任何修改或删除操作。
感谢阅读,希望对你有所帮助 :)
来源:blog.csdn.net////
推荐
请注意,由于公众号平台调整了推送机制,若您不想错过精彩内容,务必在阅读完毕后点击“在看”intellij idea golang plugin,并给文章添加“星标”。这样做可以确保每次新文章的推送都能第一时间出现在您的订阅列表中。您的支持对我们至关重要!
如有侵权请联系删除!
Copyright © 2023 江苏优软数字科技有限公司 All Rights Reserved.正版sublime text、Codejock、IntelliJ IDEA、sketch、Mestrenova、DNAstar服务提供商
13262879759
微信二维码