
近幾年「原生」一詞一直泛濫在雲計算、邊緣計算等領域中,而原生寵幸的語言也一直都是Golang,Rust等脫離Sandbox運行的開發語言。Java得益於上世紀流行的一次編譯,到處執行的理念,流行至今,但也因為這個原因,導致Java程序脫離不了JVM運行環境,使得不那麼受原生程序的青睞。在雲原生泛濫的今天,臃腫的JVM使Java應用程序對比其他語言顯得無比的龐大,各路大神也想了很多方式讓Java變的更「原生」。
Spring Native 為使用GraalVM 原生映像編譯器將 Spring 應用程序編譯為原生可執行文件提供 beta 支持,以提供通常設計為打包在輕量級容器中的原生部署選項。實際上,目標是在這個新平台上支持幾乎未修改的 Spring Boot 應用程序。
配置環境OS:Windows10 21H2IDE:IntelliJ IDEA 2022.1.3JDK:graalvm-ce-java11-22.2.0Maven:3.5.4DockerDesktopforWindows:4.12.0Spring Boot:2.7.4Spring Native:0.12.1使用 Spring Native 的應用程序應該使用 Java 11 或 Java 17 編譯。
構建 Spring Boot 原生應用程序有兩種主要方法:
方法1就是在SpringBoot2.3後,可以使用spring-boot-maven-plugin插件來構建docker鏡像,使用mvn spring-boot:build-image命令結合Docker的API來實現Spring Boot 原生應用程序的構建,成功執行後會直接生成一個docker鏡像,然後run這個鏡像就可以了,不用我們再寫Dockerfile了,相關的參數配置都在pom.xml中配置(該插件的configuration標籤下,和fabric8或spotify的docker-maven-plugin很相似)。
方法2不需要安裝docker,但要安裝Visual Studio,然後執行mvn -Pnative package命令後會生成一個可執行文件(.exe),運行即可。
主要區別如下
1 環境依賴不同因為每個微服務使用Docker部署而不是exe文件,所以方法1正好符合我的需求,所以後文使用Spring Boot Buildpacks的方式構建Spring Boot原生應用程序。
安裝Graal VM官方下載地址:
https://www.graalvm.org/downloads/





檢驗是否安裝成功

打開新的cmd,輸入以下命令,等待安裝
guinstallnative-image安裝 Docker Desktop for Windows具體步驟略,按照官方文檔操作即可:https://docs.docker.com/desktop/windows/install/
創建Springboot項目

完整的pom如下
<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="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.0https://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.7.4</version><relativePath/><!--lookupparentfromrepository--></parent><groupId>com.example</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.12.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><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes><classifier>${repackage.classifier}</classifier><image><builder>paketobuildpacks/builder:tiny</builder><env><BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE><BPE_DELIM_JAVA_TOOL_OPTIONSxml: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></configuration></plugin><plugin><groupId>org.springframework.experimental</groupId><artifactId>spring-aot-maven-plugin</artifactId><version>${spring-native.version}</version><executions><execution><id>test-generate</id><goals><goal>test-generate</goal></goals></execution><execution><id>generate</id><goals><goal>generate</goal></goals></execution></executions></plugin></plugins></build><repositories><repository><id>spring-releases</id><name>SpringReleases</name><url>https://repo.spring.io/release</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-releases</id><name>SpringReleases</name><url>https://repo.spring.io/release</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></project>本文介紹的是Spring Native0.12.1版本,其對應的Spring Boot版本必須是2.7.4,以上只是一個最基本的配置案例,實際開發中還需要在spring-boot-maven-plugin插件的configuration標籤下配置其他許許多多的參數。
例如docker遠程的地址和證書的路徑、jvm調優參數、配置文件指定、docker鏡像名端口倉庫地址等等,最好的方法就是看spring-boot-maven-plugin的官方文檔,這裡以配置jvm參數為例

配置官方文檔:
https://docs.spring.io/spring-boot/docs/2.6.2/maven-plugin/reference/htmlsingle/#build-image
為了測試我這裡配置Springboot項目端口為8888,並且添加了一個獲取當前日期的API。


執行maven命令
mvncleanmvn'-Dmaven.test.skip=true'spring-boot:build-image下載完相關依賴後,電腦就會開始構建編譯項目,查看任務管理器可以發現在構建和編譯過程中CPU利用率很高,內存使用量也很高,根據電腦配置和網絡狀態不同使用的構建時間也不相同。
構建成功如下圖:

查看所有鏡像docker images

spring-native就是構建的鏡像
創建並運行容器
dockerrun-id-p8888:8888--name=native-appspring-native:0.0.1-SNAPSHOT59178df9f49b在Docker Desktop查看日誌,發現應用成功啟動,啟動僅耗時31ms,果然印證了Spring Native啟動是毫秒級別這句話。

在Docker Desktop查看占用內存,僅46M左右。

成功調用接口

不使用Spring Native啟動應用,使用java -jar來啟動項目


啟動耗時1.5秒,占用內存高達238M。
最後附上Spring Native官方文件:
https://docs.spring.io/spring-native/docs/current/reference/htmlsingle/index.html
感謝閱讀,希望對你有所幫助:)
來源:blog.csdn.net/qq_35156196/article/details/127208514
END
關注後端面試那些事,回復【2022面經】
獲取最新大廠Java面經

