• 【Spring云原生】Spring官宣,干掉原生JVM,推出 Spring Native!整体提升性能!Native镜像技术在Spring中的应用


     🎉🎉欢迎光临🎉🎉

    🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

    🌟特别推荐给大家我的最新专栏《Spring 狂野之旅:从入门到入魔》 🚀

    本专栏带你从Spring入门到入魔!

    这是苏泽的个人主页可以看到我其他的内容哦👇👇

    努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net/

     

    Spring 团队发布了 Spring Native Beta 版。通过 Spring Native,Spring 应用将有机会与 GraalVM 原生镜像的方式运行。为了更好地支持原生运行,Spring Native 提供了 Maven 和 Gradle 插件,并且提供了优化原生配置的注解。

    Spring 发布了 Spring Native 的 beta 版本,并在http://start.spring.io上运行它。

    实际上,这意味着自Spring成立以来,除了Spring支持的常规Java虚拟机之外,我们还将添加Beta支持,以使用GraalVM将Spring应用程序编译到本机映像中,从而提供一种部署Spring应用程序的新方法。支持Java和Kotlin。

    这些本机Spring应用程序可以部署为独立的可执行文件(无需安装JVM),并提供有趣的特性,包括几乎即时启动(通常<100ms),即时峰值性能和较低的内存消耗,但所需的构建时间和运行时优化次数少于JVM。

    目录

    原理

    应用:

    Spring Native的优势包括:

    使用Spring Native

    生成Native镜像:完成上述配置后,您可以使用以下命令生成Spring应用程序的Native镜像:

    生成的Native镜像将位于target目录下。通过将Spring应用程序编译为Native镜像,可以提高应用程序的性能

    优化

    直接在编译时定义了MyClass类,避免了在运行时使用反射机制来加载类。

    部署和交付优化

    部署示例:

    使用Docker进行部署示例代码:

    使用Buildah进行部署示例代码:

    与传统JVM调优的比较


    1. 引言
      Spring Native作为Spring框架的扩展,利用Native镜像技术实现了对Spring应用程序的编译优化,从而提升应用性能和启动速度。本文将介绍Spring Native的背景和动机,以及Native镜像技术的概念和原理。

    2. 原理

    Native镜像技术是一种将Java应用程序编译成本地可执行文件的技术。它的原理是通过静态编译将整个Java应用程序及其依赖项转换为本地机器代码,从而实现更快的启动时间和较小的内存占用。

    Spring Native的主要目标是通过将Spring应用程序编译为本地镜像,提供更快的启动时间、更低的内存消耗和更好的资源利用率。通过消除JVM启动和解释阶段的开销,Spring Native可以显著减少应用程序的启动时间,并减少内存占用。

    应用:

    Spring Native的优势包括:

    1. 更快的启动时间:通过将应用程序编译为本地镜像,减少了JVM启动和解释的时间,从而实现更快的应用程序启动。

    2. 较低的内存消耗:本地镜像消除了传统Java应用程序所需的JVM内存开销,减少了内存占用,提高了资源利用率。

    3. 更好的资源利用率:由于减少了内存消耗,Spring Native可以在有限的资源环境中更有效地运行,提供更好的可伸缩性和性能。

    使用Spring Native

    使用Spring Native扩展需要以下步骤:

    1. 安装GraalVM:首先,您需要安装GraalVM。您可以从GraalVM官方网站(https://www.graalvm.org)下载适合您操作系统的GraalVM发行版,并按照官方文档进行安装。

    2. 配置GraalVM:安装完成后,您需要将GraalVM设置为默认的JDK。您可以使用以下命令将GraalVM设置为默认JDK:

    1. $ gu install native-image
    2. $ export PATH=$PATH:/path/to/graalvm/bin

    添加Spring Native依赖:在您的Spring项目中,您需要添加Spring Native的依赖。在您的项目的pom.xml文件中,添加以下依赖:

    1. <dependency>
    2. <groupId>org.springframework.experimentalgroupId>
    3. <artifactId>spring-graalvm-nativeartifactId>
    4. <version>0.10.3version>
    5. dependency>

    配置Spring Native:您需要配置Spring Native插件以指定要编译为Native镜像的类和功能。您可以在您的项目的pom.xml文件中添加以下配置:

    1. <build>
    2. <plugins>
    3. <plugin>
    4. <groupId>org.springframework.experimentalgroupId>
    5. <artifactId>spring-aot-maven-pluginartifactId>
    6. <version>0.10.3version>
    7. <executions>
    8. <execution>
    9. <goals>
    10. <goal>generategoal>
    11. goals>
    12. execution>
    13. executions>
    14. plugin>
    15. plugins>
    16. build>

    生成Native镜像:完成上述配置后,您可以使用以下命令生成Spring应用程序的Native镜像:

    1. $ mvn spring-aot:generate
    2. $ mvn package -Pnative

    生成的Native镜像将位于target目录下。通过将Spring应用程序编译为Native镜像,可以提高应用程序的性能

    优化

    • 讨论替换动态特性和反射机制的方法
       

    静态配置示例:在传统的使用Spring框架的应用程序中,通常使用XML配置文件或注解来配置Bean。这种静态配置的方式可以避免使用反射机制来实现动态的Bean实例化。

    1. @Configuration
    2. public class AppConfig {
    3. @Bean
    4. public MyService myService() {
    5. return new MyServiceImpl(); // 明确地实例化Bean
    6. }
    7. }

    在上述示例中,通过在配置类中明确地实例化Bean,避免了使用反射机制。

    明确的Bean实例化方式示例:在某些场景下,可以使用明确的实例化方式来代替反射机制。

    1. public class MyFactory {
    2. public static MyService createMyService() {
    3. return new MyServiceImpl(); // 明确地实例化Bean
    4. }
    5. }

    在上述示例中,通过使用静态工厂方法来明确地实例化Bean,避免了使用反射机制。

    替代动态特性的示例代码如下:

    1. 静态代理示例:静态代理是一种替代动态代理的方式,可以在编译时生成代理类,避免在运行时使用反射机制。
      1. public interface MyService {
      2. void doSomething();
      3. }
      4. public class MyServiceImpl implements MyService {
      5. @Override
      6. public void doSomething() {
      7. // 实现具体的业务逻辑
      8. }
      9. }
      10. public class MyServiceProxy implements MyService {
      11. private MyService target;
      12. public MyServiceProxy(MyService target) {
      13. this.target = target;
      14. }
      15. @Override
      16. public void doSomething() {
      17. // 在调用目标对象之前或之后,可以添加额外的逻辑
      18. // ...
      19. target.doSomething();
      20. // 在调用目标对象之前或之后,可以添加额外的逻辑
      21. // ...
      22. }
      23. }

    2. 编译时生成代码示例:在某些场景下,可以使用编译时生成代码的方式来替代动态加载类。
      1. public class MyClass {
      2. public void doSomething() {
      3. // 实现具体的业务逻辑
      4. }
      5. }

      直接在编译时定义了MyClass类,避免了在运行时使用反射机制来加载类。

    部署和交付优化

    • Native镜像的部署可以直接使用常见的构建工具包括Docker和Buildah。
    • 使用构建好的Native镜像,可以在目标环境中进行部署和运行。这可以通过使用容器管理平台(如Docker Swarm或Kubernetes)来实现,也可以直接在本地或云环境中运行。

    部署示例:

    使用Docker进行部署示例代码:

    1. # Dockerfile
    2. FROM scratch
    3. COPY my_app /my_app
    4. CMD ["/my_app"]

    上述示例已经有一个名为 my_app 的本地机器代码可执行文件。在构建镜像时,将可执行文件复制到镜像中并设置其作为容器的默认命令。

    构建Docker镜像的命令如下(假设 Dockerfile 和可执行文件在同一目录下):

    docker build -t my_app_image .

     运行Docker容器的命令如下:

    docker run -d my_app_image

    这将在后台运行名为 my_app_image 的容器,并执行 my_app 可执行文件。

    使用Buildah进行部署示例代码:

    1. # 构建本地镜像
    2. buildah bud -t my_app_image .
    3. # 创建容器
    4. container=$(buildah from my_app_image)
    5. # 将可执行文件复制到容器中
    6. buildah copy $container my_app /my_app
    7. # 设置容器的默认命令
    8. buildah config --cmd ["/my_app"] $container
    9. # 保存容器为镜像
    10. buildah commit $container my_app_image
    11. # 运行镜像
    12. podman run -d my_app_image

    与传统JVM调优的比较

    1. 编译方式:传统JVM调优主要关注在运行时对JVM进行优化,包括调整垃圾回收器、调整堆内存大小、调整线程池参数等。而Spring Native则采用了提前编译的方式,将应用程序及其依赖项编译为本地机器代码,以提高性能和启动时间。

    2. 依赖项处理:在传统JVM调优中,依赖项通常以JAR文件的形式打包,并在运行时通过类加载器进行动态加载。而Spring Native会对依赖项进行静态分析和静态链接,将它们与应用程序一起编译为本地机器代码,减少了依赖项的加载和解析时间。

  • 相关阅读:
    IDEA在多线程环境下断点调试-验证synchronized监视锁的运行状态
    腾讯云上创建 对象存储cos
    IB的IA EE TOK区别介绍
    MySQL初识
    Google Earth Engine(GEE) 03-矢量数据类型
    如何利用exceljs将data数据导出表格实现日期去重,同时保留对应日期的每一列数据
    前端数字计算精度问题
    FFmpeg的API库介绍
    数学建模——最优连接(基于最小支撑树)
    LED电子显示屏的异步图文控制技术
  • 原文地址:https://blog.csdn.net/m0_72803988/article/details/136440635