在GraalVM中部署執行Spring Boot應用 - Indrek Ots
GraalVM是一種高效能的多語言虛擬機器,用於執行以JavaScript等基於LLVM的各種語言編寫的應用程式。對於Java應用也可作為通常JVM的替代,它更具有效能優勢。GraalVM帶來的一個有趣功能是它能夠在建立JVM應用程式的提前編譯(create ahead-of-time:AOT)本機映象,從而保證了更快的啟動時間和更低的記憶體佔用。在本文中,我們將重點介紹如何建立Spring應用的本機二進位制檔案。
GraalVM Native Image 101
Java應用程式使用編譯為位元組碼javac。在應用程式執行時,JVM將類檔案載入到記憶體中,並分析程式的效能以獲取熱點。因此名稱為“ HotSpot JVM ”。在剛剛在時間(JIT)編譯器編譯這些重複執行為本機程式碼應用程式的部分。 但是,JIT編譯需要處理器時間和記憶體,這會影響應用程式的啟動時間。
GraalVM原生本機映象能提前將 JVM應用程式編譯為當前機器的機器程式碼。它靜態分析應用程式的位元組碼,找到所有可以訪問的類和方法,並將它們編譯為本地可執行檔案。輸出是特定於平臺的可執行二進位制檔案。
例如,讓我們從以下“ Hello World”程式構建原生映象。
class HelloWorld { public static void main(String[] args) { System.out.println("Hello World"); } } |
首先,我們需要使用 javac:
$ javac HelloWorld.java |
然後用native-image將這個類檔案構建成可執行二進位制檔案。
$ native-image HelloWorld |
要啟動應用程式,只需:
$ ./helloworld Hello World |
本機映象Java限制
GraalVM本機映象靜態分析是需要假設在封閉世界的前提下。它需要在映象生成期間提前知道所有可能訪問的位元組碼。因此,並非所有Java功能都受支援:例如,不支援動態類的載入/解除安裝。反射需要配置。CGLIB代理不適用,但是卻支援JDK代理,還需要配置。此外,您還需要告訴本機映象有關所有資源訪問的資訊。
配置以JSON文件的形式提供。例如,要配置反射,您可以建立以下檔案,並使用-H:ReflectionConfigurationFiles命令列標誌來指定命令的檔案位置native-image。
[ { "name":"java.lang.Object" }, { "name":"org.apache.naming.factory.ResourceFactory", "methods" : [{"name": "<init>","parameterTypes":[]}] }, ... ] |
配置動態代理、JNI和資源訪問時都需要建立類似的檔案來。但是,手工完成所有這些工作需要很多工作,尤其是在我們處理大型應用程式時。幸運的是,有一個Java代理可以生成配置。它觀察在JVM中執行的應用程式的行為,並生成生成本機映像所需的配置檔案。
要獲得完整的配置檔案集,您需要在應用程式中使用所有程式碼路徑。具有100%覆蓋率的測試套件可以解決問題,但實際上,測試套件永遠不會測試所有路徑。因此,也可能需要手動修改這些配置檔案。
Spring和GraalVM本機映像
從Spring Framework 5.1 開始,提供了對GraalVM本機映像的初始支援。 5.2開發週期的重點是改進整合和全面支援,而不需要額外的配置或變通辦法,這是即將到來的Spring Framework 5.3發行版的主題之一。
在spring-graal-nativeGithub上庫展示瞭如何從Spring啟動應用程式構建本地映象的例子。該專案實施了GraalFeature,在配置反射,代理等方面承擔了繁重的工作。
看看Spring Boot帶有Tomcat的Spring MVC示例:請記住,在撰寫本文時,該示例期望您正在使用GraalVM 19.2.1,並且已native-image安裝外掛。在構建示例之前,我們需要編譯Spring Graal Feature。github儲存庫的根目錄具有一個bash指令碼來執行此操作。
$ ./build-feature.sh |
$ ./springmvc-tomcat . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: ... INFO: Started TomcatApplication in 0.054 seconds (JVM running for 0.057) |
注意0.054秒的快速啟動時間。為了進行比較,在JVM中執行應用程式時,報告的啟動時間為1.455秒。
總結
GraalVM本機映像使我們能夠構建提前編譯的JVM應用程式,這些應用程式啟動速度非常快,並且使用的記憶體更少。這對於短暫的過程絕對是有用的,尤其是在無伺服器的情況下(按毫秒計費)。
由於類路徑掃描和自動配置,Spring Boot應用程式在啟動期間非常佔用CPU。當在共享主機上同時啟動多個Spring Boot應用程式時,它們開始爭奪CPU,啟動時間增加。編排工具甚至可能終止程式,因為它們啟動得不夠快。快速啟動的提前編譯的Spring Boot應用程式可能是該問題的答案。
容器化的Spring Boot應用程式也會有所收穫。由於本機二進位制檔案具有所需的一切,因此不再需要將JRE烘焙到容器中。我們可以構建較小的Docker映像。
一些以微服務為重點的框架已經利用了本機影象功能(例如Quarkus,Micronaut,Helidon)。儘管Spring Boot尚未完全支援本機映像生成,但我認為它將是該框架的重要補充。
相關文章
- 將Spring Boot應用變成GraalVM本機映象快速執行 - codecentricSpring BootLVM
- Hazelcast JET在Spring Boot上執行ASTSpring Boot
- 通往Spring Boot本機應用的道路:Spring GraalVM Native 0.7.0可以使用了 - spring.ioSpring BootLVM
- Spring Boot應用中進行任務排程Spring Boot
- 在 OpenFunction 中執行 Serverless 應用FunctionServer
- 在Spring Boot應用啟動時如何執行程式碼? -DukesletterSpring Boot行程
- 使用Spring Boot和GraalVM在Knative上構建微服務 - piotrSpring BootLVM微服務
- Spring Boot Serverless 實戰系列“部署篇” | Mall 應用Spring BootServer
- Spring Boot 應用程式中的 QueryDSLSpring Boot
- 在 SAP 雲平臺上部署和執行 Docker 應用Docker
- 在Spring Boot應用程式中使用Kubernetes ConfigMapSpring Boot
- Guava Cache本地快取在 Spring Boot應用中的實踐Guava快取Spring Boot
- 在Docker中部署Spring Boot專案DockerSpring Boot
- 利用神器BTrace 追蹤線上 Spring Boot應用執行時資訊Spring Boot
- 如何使用ParcelJS在Spring Boot應用程式中打包前端 - codecentric AG BlogJSSpring Boot前端
- 結合GraalVM與Spring Native的Spring Boot原始碼教程 | foojayLVMSpring Boot原始碼
- Ooui:在瀏覽器中執行.NET應用UI瀏覽器
- Spring Boot執行緒安全指南Spring Boot執行緒
- 如何執行Spring Boot專案Spring Boot
- spring boot 執行sql檔案Spring BootSQL
- Spring Boot中如何使用Ostara監控應用?Spring Boot
- Web應用部署在WebLogic中Basic認證無法執行問題及解決Web
- 使用SDM快速部署Spring Boot應用到KubernetesSpring Boot
- 自然語言處理工具包 HanLP在 Spring Boot中的應用自然語言處理HanLPSpring Boot
- 如何在Spring Boot應用啟動之後立刻執行一段邏輯Spring Boot
- Spring Boot 2.0(四):使用 Docker 部署 Spring BootSpring BootDocker
- Reactor執行緒模型及其在Netty中的應用React執行緒模型Netty
- golang執行緒池在IO多路複用中的應用Golang執行緒
- Spring Native釋出:使用GraalVM將Spring應用編譯為本機映象SpringLVM編譯
- Spring Boot應用程式中的常用註釋列表Spring Boot
- 剖析 SPI 在 Spring 中的應用Spring
- Spring boot應用如何支援httpsSpring BootHTTP
- Spring Boot 之路(一):一個簡單的Spring Boot應用Spring Boot
- spring-boot-route(十八)spring-boot-adtuator監控應用Springboot
- 在IntelliJ idea中使用docker除錯Spring Boot應用程式IntelliJIdeaDocker除錯Spring Boot
- 在spring boot專案(maven)中引入其他 spring boot專案Spring BootMaven
- Spring Boot(十二):Spring Boot 如何測試打包部署Spring Boot
- 在Docker容器中執行ASP.NET MVC應用程式DockerASP.NETMVC