<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          這樣優(yōu)化,0.059s 啟動(dòng)一個(gè)SpringBoot項(xiàng)目

          共 12974字,需瀏覽 26分鐘

           ·

          2022-12-22 07:29

          來源:blog.csdn.net/weixin_43553153/article/details/12248676

          前言

          最近自己用Spring Cloud Alibaba做了一個(gè)微服務(wù)架構(gòu)的項(xiàng)目,部署的時(shí)候遇到了難題:內(nèi)存不夠。目前該項(xiàng)目有7個(gè)微服務(wù),因?yàn)槲抑挥幸慌_阿里云的服務(wù)器(2C 4G),所以我只能把所有的微服務(wù)部署在一臺服務(wù)器上,部署方式是使用docker制作springboot的fat jar鏡像,每個(gè)微服務(wù)在不加任何JVM調(diào)優(yōu)參數(shù)的情況下所占內(nèi)存約500M。

          由于是微服務(wù)所以肯定還要部署:nacos,除此之外還用到了redis、sentinel、rocketmq、elk等(mysql買的阿里云的),光是運(yùn)行這些應(yīng)用就占用內(nèi)存2個(gè)多G,剩下的1個(gè)多G內(nèi)存在部署4個(gè)微服務(wù)后就滿了,于是開始對springboot應(yīng)用的內(nèi)存進(jìn)行初步優(yōu)化:

          添加JVM參數(shù)優(yōu)化內(nèi)存大小

          # JVM初始分配的內(nèi)存由-Xms指定,默認(rèn)是物理內(nèi)存的1/64
          -Xms128m
          # JVM最大分配的內(nèi)存由-Xmx指定,默認(rèn)是物理內(nèi)存的1/4
          -Xmx128m
          # 規(guī)定了每個(gè)線程虛擬機(jī)棧及堆棧的大小,一般情況下,256k是足夠的,此配置將會(huì)影響此進(jìn)程中并發(fā)線程數(shù)的大小。
          -Xss256k
          # 指定并行GC線程的數(shù)量,一般最好和CPU核心數(shù)量相當(dāng)
          -XX:ParallelGCThreads=2

          默認(rèn)空余堆內(nèi)存小于40%時(shí),JVM就會(huì)增大堆直到-Xmx的最大限制;空余堆內(nèi)存大于70%時(shí),JVM會(huì)減少堆直到 -Xms的最小限制。

          因此服務(wù)器一般設(shè)置-Xms、-Xmx相等以避免在每次GC 后調(diào)整堆的大小。對象的堆內(nèi)存由稱為垃圾回收器的自動(dòng)內(nèi)存管理系統(tǒng)回收。

          默認(rèn)情況下,當(dāng) CPU 數(shù)量小于8, ParallelGCThreads 的值等于 CPU 數(shù)量,我的服務(wù)器是2C的所以這個(gè)參數(shù)可省略。配置完成后,啟動(dòng)服務(wù)發(fā)現(xiàn)內(nèi)存確實(shí)變小了,由原來的500M降至100~200M,但不是我想要的效果,我期望的效果是達(dá)到幾十M的級別。

          經(jīng)網(wǎng)上查閱大量資料得知可以使用Spring Native這門新技術(shù)來實(shí)現(xiàn)我的需求。(該技術(shù)正處于快速迭代階段,變動(dòng)較大,建議用于個(gè)人學(xué)習(xí),不要用于生產(chǎn))

          SpringBoot項(xiàng)目使用Spring Native后:

          1. 應(yīng)用啟動(dòng)速度特別快,毫秒級別
          2. 運(yùn)行時(shí)更低的內(nèi)存消耗,官方展示的含有Spring Boot, Spring MVC, Jackson, Tomcat的鏡像大小是50M
          3. 為了達(dá)到前面的效果,代價(jià)是構(gòu)建時(shí)間更長(即使是一個(gè)Hello Word構(gòu)建也需要2分鐘,不過主要取決于電腦配置,我的是2min左右)

          Spring Native是什么

          簡而言之就是為了提高Java在云原生的競爭力(個(gè)人理解)。

          以下內(nèi)容摘抄自GitHub上Spring Native的自述文件:

          Spring Native 為使用GraalVM 原生映像編譯器將 Spring 應(yīng)用程序編譯為原生可執(zhí)行文件提供 beta 支持,以提供通常設(shè)計(jì)為打包在輕量級容器中的原生部署選項(xiàng)。實(shí)際上,目標(biāo)是在這個(gè)新平臺上支持幾乎未修改的 Spring Boot 應(yīng)用程序。

          以下內(nèi)容摘抄自其他博客:

          近幾年“原生”一詞一直泛濫在云計(jì)算、邊緣計(jì)算等領(lǐng)域中,而原生寵幸的語言也一直都是Golang,Rust等脫離Sandbox運(yùn)行的開發(fā)語言。Java得益于上世紀(jì)流行的一次編譯,到處執(zhí)行的理念,流行至今,但也因?yàn)檫@個(gè)原因,導(dǎo)致Java程序脫離不了JVM運(yùn)行環(huán)境,使得不那么受原生程序的青睞。在云原生泛濫的今天,臃腫的JVM使Java應(yīng)用程序?qū)Ρ绕渌Z言顯得無比的龐大,各路大神也想了很多方式讓Java變的更“原生”。

          圖片

          實(shí)戰(zhàn)

          本次實(shí)戰(zhàn)相關(guān)的環(huán)境信息如下:

          • OS:Windows10 21H1
          • IDE:IntelliJ IDEA 2021.2.3
          • JDK:graalvm-ce-java11-21.3.0
          • Maven:3.6.3
          • Docker Desktop for Windows: 20.10.12
          • Spring Boot:2.6.2
          • Spring Native:0.11.1
          圖片

          從官方文檔得知(上圖)

          使用 Spring Native 的應(yīng)用程序應(yīng)該使用 Java 11 或 Java 17 編譯。

          構(gòu)建 Spring Boot 原生應(yīng)用程序有兩種主要方法:

          1. 使用Spring Boot Buildpacks 支持生成包含本機(jī)可執(zhí)行文件的輕量級容器。
          2. 使用GraalVM 原生鏡像 Maven 插件支持生成原生可執(zhí)行文件。

          經(jīng)過各種踩坑后在本機(jī)上成功的使用了方法1和方法2。簡單來說:

          方法1就是在SpringBoot2.3后,可以使用spring-boot-maven-plugin插件來構(gòu)建docker鏡像,使用mvn spring-boot:build-image命令結(jié)合Docker的API來實(shí)現(xiàn)Spring Boot 原生應(yīng)用程序的構(gòu)建,成功執(zhí)行后會(huì)直接生成一個(gè)docker鏡像,然后run這個(gè)鏡像就可以了,不用我們再寫Dockerfile了,相關(guān)的參數(shù)配置都在pom.xml中配置(該插件的configuration標(biāo)簽下,和fabric8spotifydocker-maven-plugin很相似)。

          方法2不需要安裝docker,但要安裝Visual Studio,然后執(zhí)行mvn -Pnative package命令后會(huì)生成一個(gè)可執(zhí)行文件(.exe),運(yùn)行即可。

          主要區(qū)別如下

          1 環(huán)境依賴不同
          • 方法1需要安裝Docker
          • 方法2需要安裝Visual Studio(需要用到部分單個(gè)組件:2個(gè)MSVC,1個(gè)Windows 10 SDK)
          2 執(zhí)行的maven命令不同
          • 方法1是mvn spring-boot:build-image
          • 方法2是mvn -Pnative package

          因?yàn)槊總€(gè)微服務(wù)使用Docker部署而不是exe文件,

          所以方法1正好符合我的需求,

          所以后文使用Spring Boot Buildpacks的方式構(gòu)建Spring Boot原生應(yīng)用程序。

          1 安裝Graal VM(graalvm-ce-java11-windows-amd64)

          官方下載地址:

          https://www.graalvm.org/downloads/

          圖片
          圖片

          2 配置環(huán)境變量

          圖片
          圖片
          圖片

          針對方法1的話,上面三張圖好像只用配置JAVA_HOME就行,

          想一次成功的話建議3個(gè)都配,后續(xù)可以自行測試。

          檢驗(yàn)是否安裝成功

          圖片

          3 安裝native-image

          打開新的cmd,輸入以下命令,等待安裝

          gu install native-image

          這一步我執(zhí)行失敗了,解決方法就是從github上

          手動(dòng)下載native-image,然后解壓、安裝

          https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-21.3.0/native-image-installable-svm-java11-windows-amd64-21.3.0.jar

          jar用WinRAR也是可以解壓的,解壓后如下

          圖片

          在bin目錄下打開cmd,輸入以下命令,等待安裝

          $ gu install -L native-image*

          4 安裝 Desktop for Windows

          具體步驟略,按照官方文檔操作即可:

          https://docs.docker.com/desktop/windows/install/

          5 配置pom.xml

          前面都是準(zhǔn)備工作,這一步開始才是重點(diǎn)

          首先快速創(chuàng)建一個(gè)Spring Boot項(xiàng)目,我命名為spring-native

          完整的pom如下

          <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
              <modelVersion>4.0.0</modelVersion>
              <parent>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-parent</artifactId>
                  <version>2.6.2</version>
                  <relativePath/> <!-- lookup parent from repository -->
              </parent>
              <groupId>ltd.pcdd</groupId>
              <artifactId>spring-native</artifactId>
              <version>0.0.1-SNAPSHOT</version>
              <name>spring-native</name>
              <description>spring-native</description>
              <properties>
                  <java.version>11</java.version>
                  <repackage.classifier/>
                  <spring-native.version>0.11.1</spring-native.version>
              </properties>

              <dependencies>
                  <dependency>
                      <groupId>org.springframework.boot</groupId>
                      <artifactId>spring-boot-starter-web</artifactId>
                  </dependency>
                  
                  <dependency>
                      <groupId>org.springframework.experimental</groupId>
                      <artifactId>spring-native</artifactId>
                      <version>${spring-native.version}</version>
                  </dependency>
              </dependencies>

              <build>
                  <plugins>
                      <plugin>
                          <groupId>org.springframework.experimental</groupId>
                          <artifactId>spring-aot-maven-plugin</artifactId>
                          <version>0.11.1</version>
                          <executions>
                              <execution>
                                  <id>generate</id>
                                  <goals>
                                      <goal>generate</goal>
                                  </goals>
                              </execution>
                          </executions>
                      </plugin>

                      <!--Spring Boot 2.3發(fā)布后帶來了新特性之一就是對構(gòu)建鏡像的便捷支持-->
                      <plugin>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-maven-plugin</artifactId>
                          <configuration>
                              <image>
                                  <builder>paketobuildpacks/builder:tiny</builder>
                                  <env>
                                      <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
                                  </env>
                              </image>
                          </configuration>
                      </plugin>
                  </plugins>
              </build>

              <repositories>
                  <repository>
                      <id>spring-release</id>
                      <name>Spring release</name>
                      <url>https://repo.spring.io/release</url>
                  </repository>
              </repositories>

              <pluginRepositories>
                  <pluginRepository>
                      <id>spring-release</id>
                      <name>Spring release</name>
                      <url>https://repo.spring.io/release</url>
                  </pluginRepository>
              </pluginRepositories>

          </project>

          本文介紹的是Spring Native0.11.1版本,

          其對應(yīng)的Spring Boot版本必須是2.6.2,

          以上只是一個(gè)最基本的配置案例,

          實(shí)際開發(fā)中還需要在spring-boot-maven-plugin插件

          的configuration標(biāo)簽下配置其他許許多多的參數(shù)。

          例如docker遠(yuǎn)程的地址和證書的路徑、jvm調(diào)優(yōu)參數(shù)、

          配置文件指定、docker鏡像名端口倉庫地址等等,

          最好的方法就是看spring-boot-maven-plugin的官方文檔,

          這里以配置jvm參數(shù)為例

          圖片

          通過官方文檔得知只需要在configuration標(biāo)簽下配置即可,例如

          <image>
           <builder>paketobuildpacks/builder:tiny</builder>
           <env>
            <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>
            <BPE_DELIM_JAVA_TOOL_OPTIONS xml:space="preserve"> </BPE_DELIM_JAVA_TOOL_OPTIONS>
            <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xms128m</BPE_APPEND_JAVA_TOOL_OPTIONS>
            <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xmx128m</BPE_APPEND_JAVA_TOOL_OPTIONS>
            <BPE_APPEND_JAVA_TOOL_OPTIONS>-Xss256k</BPE_APPEND_JAVA_TOOL_OPTIONS>
            <BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:ParallelGCThreads=2</BPE_APPEND_JAVA_TOOL_OPTIONS>
            <BPE_APPEND_JAVA_TOOL_OPTIONS>-XX:+PrintGCDetails</BPE_APPEND_JAVA_TOOL_OPTIONS>
           </env>
          </image>

          其他的配置參數(shù)還有很多。

          官方文檔:

          https://docs.spring.io/spring-boot/docs/2.6.2/maven-plugin/reference/htmlsingle/#build-image

          6 執(zhí)行maven命令

          mvn clean
          mvn '-Dmaven.test.skip=true' spring-boot:build-image

          下載完相關(guān)依賴后,電腦風(fēng)扇就開始呼呼的轉(zhuǎn),查看任務(wù)管理器發(fā)現(xiàn)

          CPU利用率100%,內(nèi)存使用量飆升,最后穩(wěn)定在90%+。

          構(gòu)建成功

          圖片

          7 創(chuàng)建并運(yùn)行容器

          查看所有鏡像

          圖片

          spring-native就是構(gòu)建的鏡像

          創(chuàng)建并運(yùn)行容器

          圖片

          Docker Desktop查看日志,發(fā)現(xiàn)應(yīng)用成功啟動(dòng),啟動(dòng)僅耗時(shí)。

          也就是59ms,果然印證了Spring Native啟動(dòng)是毫秒級別這句話。

          圖片

          成功調(diào)用接口

          圖片

          Docker Desktop查看占用內(nèi)存,僅28M左右。

          圖片

          不使用Spring Native啟動(dòng)應(yīng)用

          圖片
          圖片

          啟動(dòng)耗時(shí)3s,占用內(nèi)存高達(dá)511M,高下立判。

          文章僅供參考,建議結(jié)合Spring Native官方最新文檔學(xué)習(xí)。


          ------
          我們創(chuàng)建了一個(gè)高質(zhì)量的技術(shù)交流群,與優(yōu)秀的人在一起,自己也會(huì)優(yōu)秀起來,趕緊點(diǎn)擊加群,享受一起成長的快樂。另外,如果你最近想跳槽的話,年前我花了2周時(shí)間收集了一波大廠面經(jīng),節(jié)后準(zhǔn)備跳槽的可以點(diǎn)擊這里領(lǐng)取!

          推薦閱讀

          ··································

          你好,我是程序猿DD,10年開發(fā)老司機(jī)、阿里云MVP、騰訊云TVP、出過書創(chuàng)過業(yè)、國企4年互聯(lián)網(wǎng)6年。從普通開發(fā)到架構(gòu)師、再到合伙人。一路過來,給我最深的感受就是一定要不斷學(xué)習(xí)并關(guān)注前沿。只要你能堅(jiān)持下來,多思考、少抱怨、勤動(dòng)手,就很容易實(shí)現(xiàn)彎道超車!所以,不要問我現(xiàn)在干什么是否來得及。如果你看好一個(gè)事情,一定是堅(jiān)持了才能看到希望,而不是看到希望才去堅(jiān)持。相信我,只要堅(jiān)持下來,你一定比現(xiàn)在更好!如果你還沒什么方向,可以先關(guān)注我,這里會(huì)經(jīng)常分享一些前沿資訊,幫你積累彎道超車的資本。

          點(diǎn)擊領(lǐng)取2022最新10000T學(xué)習(xí)資料

          瀏覽 37
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  热久久久 | 无码在线电影 | 影音先锋成人无码在线观看 | 亚洲黄色五月天 | 久草电影男人天堂 |