云原生应用之--SpringNative 实战

简介: 云原生应用之--SpringNative 实战

1.1 Graalvm

1.1.1 简介

GraalVM 是一种高性能运行时,可显着提高应用程序性能和效率,非常适合微服务. 对于 Java 程序 GraalVM 负责将 Java 字节码编译成机器码,映像生成过程使用静态分析来查找可从主 Java 方法访问的任何代码,然后执行完全提前 (AOT) 编译。生成的本机二进制文件包含机器代码形式的整个程序,以便立即执行。

1.

1.1.2 环境准备

  • Brew 安装

  brew install --cask graalvm/tap/graalvm-ce-lts-java11

  gu install native-image

1.2.1.2.

复制

  • 下载安装
  1. 下载 GraalVM : https://www.graalvm.org/downloads/
  2. 配置环境变量:JAVA_HOME 和 PATH
  3. 运行 gu install native-image

1.1.3 运行 demo

// 创建 HelloWorld.java 文件

public class HelloWorld {

   public static void main(String[] args) {

   

       System.out.println("Hello, World!");

   }

}

// 执行编译

javac HelloWorld.java

native-image HelloWorld

//运行

./helloworld

Hello, World!

1.2.3.4.5.6.7.8.9.10.11.12.13.1.2.3.4.5.6.7.8.9.10.11.12.13.

复制

1.2 Spring Native

1.2.1 简介

Spring Native 原生镜像可以在许多场景下降低工作负载,包括微服务,函数式服务,非常适合容器和 Kubernetes。优点:快速启动,提高峰值性能以及降低内存消耗缺点:构建过程慢, 预热后的运行时优化少常规 JVM 和此本机映像平台之间的主要区别:

  • 在构建时会从主入口点对应用程序进行静态分析。
  • 在构建时将未使用的零件删除。
  • 反射,资源和动态代理需要配置。
  • 类路径在构建时是固定的。
  • 没有类延迟加载:可执行文件中附带的所有内容都将在启动时加载到内存中。
  • 一些代码将在构建时运行。
  • 一些 Java 切面类的特性未得到完全支持。组成模块Spring Native 由以下模块组成:
  • spring-native:运行Spring Native所需的运行时依赖,还提供了Native hints API。
  • spring-native-configuration:Spring AOT 插件使用的 Spring 类的配置提示,包括各种 Spring Boot 自动配置。
  • spring-native-docs:参考指南,采用 asciidoc 格式。
  • spring-native-tools:用于查看镜像构建配置和输出的工具。
  • spring-aot:Maven 和 Gradle 插件公共的 AOT 转换基础架构。
  • spring-aot-gradle-plugin:AOT 转换的 Gradle 插件。
  • spring-aot-maven-plugin:AOT 转换的 Maven 插件。
  • samples:包含各种演示功能用法的示例,也用于集成测试。

2. 快速上手

主要有两种的方式来构建 Spring Boot 原生应用:使用 Spring Boot Buildpacks Support 生成一个包含本地可执行文件的轻量级容器。使用 GraalVM native image Maven plugin support 来生成本地可执行文件。

2.1 通过 Buildpacks 上手

2.1.1 系统要求

需要安装 Docker,并至少分配 8G 内存, 以及更多的 CPU

2.1.2 初始化 DEMO 项目

通过 https://start.spring.io/ 初始化 demo 工程

2.1.3 构建原生应用

可以按以下命令构建本地应用程序:

  • Maven $ mvn spring-boot:build-image
2.1.3.1 编译加速

资料:https://paketo.io/docs/howto/configuration/直接执行编译命令,因为要从 github 下载相关依赖,会非常慢,慢到你怀疑人生, 而且大多数时候会下载失败, 如图image.png则可以通过以下方法进行加速

  1. 下载构建需要的文件到本地,或上传到 OSS

https://github.com/graalvm/graalvm-ce-builds/releases/tag/vm-21.3.0

graalvm-ce-java11-linux-amd64-21.3.0.tar.gz

graalvm-ce-java11-linux-amd64-21.3.0.tar.gz.sha256 (sha256校验码)

native-image-installable-svm-java11-linux-amd64-21.3.0.jar

native-image-installable-svm-java11-linux-amd64-21.3.0.jar.sha256 (sha256校验码)

1.2.3.4.5.1.2.3.4.5.

复制

  1. 在工程根目录 bindings/dependency-mapping 创建 binding 文件
  2. 创建 type 文件:echo ‘dependency-mapping’ >type
  3. 查看文件校验码

也可以通过 https://github.com/paketo-buildpacks/graalvm/blob/main/buildpack.toml 网站进行查看

  1. 在工程根目录 bindings/dependency-mapping 创建 mapping 文件
  • 本地文件方式

echo 'file://{docker 内文件目录}/graalvm-ce-java11-linux-amd64-21.3.0.tar.gz'>3a1bc8eaf0518c128aaacb987ceb0b0e288776f48af630c11c01fd31122d93fa

echo 'file://{docker 内文件目录}/native-image-installable-svm-java11-linux-amd64-21.3.0.jar'>8958d4e0cad07340db0cf9e871776809e2f08fe0c93960f728fec75c4a96764f

1.2.1.2.

复制

  • Oss 方式

echo 'https://max-volador.oss-cn-hangzhou.aliyuncs.com/graalvm/dependency/graalvm-ce-java11-linux-amd64-21.3.0.tar.gz'>3a1bc8eaf0518c128aaacb987ceb0b0e288776f48af630c11c01fd31122d93fa

echo 'https://max-volador.oss-cn-hangzhou.aliyuncs.com/graalvm/dependency/native-image-installable-svm-java11-linux-amd64-21.3.0.jar'>8958d4e0cad07340db0cf9e871776809e2f08fe0c93960f728fec75c4a96764f

1.2.1.2.

复制

  1. 最后一步, 修改 pom.xml 配置,配置完成后就可以快乐的执行编译命令

<plugin>

  <groupId>org.springframework.boot</groupId>

  <artifactId>spring-boot-maven-plugin</artifactId>

  <configuration>

     <classifier>${repackage.classifier}</classifier>

     <image>

        <builder>paketobuildpacks/builder:tiny</builder>

        <env>

           <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE>

           <SERVICE_BINDING_ROOT>/bindings</SERVICE_BINDING_ROOT>

        </env>

        <!-- 文件挂载 -->

        <bindings>

           <binding>${basedir}/bindings/dependency-mapping:/bindings/dependency-mapping</binding>

           <!--suppress UnresolvedMavenProperty -->

           <binding><absolute-binding-path>: {docker 内文件目录} </binding>

        </bindings>

     </image>

  </configuration>

</plugin>

1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.

2.1.4 运行原生应用

$ docker run --rm -p 8080:8080 demo:0.0.1-SNAPSHOT

1.1.

复制

2.2 通过原生镜像的 Maven 插件上手

2.2.1 系统要求

  1. Docker 8G 以上内存
  2. Graalvm 环境

2.2.2 初始化 DEMO 项目

通过 https://start.spring.io/ 初始化 demo 工程

2.2.3 构建原生应用

$ mvn -Pnative-image package上面的命令会创建一个本地可执行文件,该可执行文件在 target 目录中。

2.2.4 运行原生应用程序

$ ./target/demo

3. 开发进阶

3.1 Spring AOT

Spring AOT构建插件旨在通过利用应用程序的上下文(类路径,配置)来生成和编译源代码,从而改善本机图像的兼容性和占用空间。

3.1.1 Maven

<build>

   <plugins>

       <!-- ... -->

       <plugin>

           <groupId>org.springframework.experimental</groupId>

           <artifactId>spring-aot-maven-plugin</artifactId>

           <version>0.10.4</version>      

           <configuration>

               <removeSpelSupport>true</removeSpelSupport>

               <removeUnusedConfig>true</removeUnusedConfig>

               <removeYamlSupport>true</removeYamlSupport>

               <removeXmlSupport>false</removeXmlSupport>

           </configuration>

           <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>

1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.

复制

3.1.2 配置 Spring AOT

  • mode 切换插件真实为本地镜像编译器提供多少配置:
  • native (默认)提供本地镜像以及代理的资源,初始化,代理和反射(使用自动配置提示)配置。
  • native-init 如果仅希望提供初始化配置和替换,则应使用。
  • native-agent 正在使用跟踪代理程序生成的配置作为基础,并且还为控制器等组件提供了其他提示。
  • removeXmlSupporttrue 默认情况下设置为 true,优化空间占用,将其设置为 false 恢复 Spring XML 支持(XML converters, codecs and XML application context support)。
  • removeSpelSupport默认情况下设置为 false,设置为 true 删除 Spring SpEL 支持以优化空间占用(应仅在不需要 SpEL 的应用中使用)。
  • removeYamlSupport 默认情况下设置为 false,设置为则true 删除Spring Boot Yaml支持以优化空间占用。
  • removeJmxSupport 默认情况下设置为 true,以优化空间占用,将其设置为false 恢复 Spring Boot JMX支持。
  • verify 默认情况下设置为 true,执行一些自动验证以确保应用可以本地编译, 设置为 false 关闭验证。
  • debugVerify 默认设置为false,设置为 true 时启用验证调试。
  • removeUnusedConfig默认情况下设置为 true,设置为 false 禁用删除未使用的配置。
  • failOnMissingSelectorHint 默认情况下设置为 true,如果没有为激活的选择器提供提示数据,则抛出错误,设置为 false 将插件从抛出错误切换为警告。
  • [Experimental] buildTimePropertiesMatchIfMissing 默认设置为 true。将其设置为 false 意味着指定 matchIfMissing=true 的任何属性都将被覆盖且不报错。
  • [Experimental] buildTimePropertiesChecks(实验)打开一些与属性相关的配置条件构建时间的评估。它必须至少包含 default-include-all或 default-exclude-all 的初始参数, 然后可以使用逗号分隔的前缀列表,以明确包含或排除(例如 default-include-all,!spring.dont.include.these.,!or.these 或 default-exclude-all,spring.include.this.one.though.,and.this.one)。前缀匹配最长的属性将会被应用(如果属性与多个前缀匹配)。

3.1.3. native-image 配置

Spring Native 通过 Spring AOT build plugin 在 META-INF/native-image 下自动生成配置文件 native-image.properties,reflect-config.json,proxy-config.json 或 resource-config.json:

3.2 Spring-native 扩展

3.2.1 通过 @NativeHint 实现

@NativeHint(options = "native-image 命令行参数",

types="反射类配置",

aotProxies="复杂代理类配置",

jdkProxies="JDK 动态代理类配置",

serializables="序列化类配置,

resources="资源文件配置",

initialization="应该在构建时或运行时显式初始化的类/包",

imports="共享类导入")

@NativeHint(options = {"-H:+ReportExceptionStackTraces"})

1.2.3.4.5.6.7.8.9.10.11.1.2.3.4.5.6.7.8.9.10.

复制

3.2.2 通过 配置文件实现

在 META-INF/native-image 下 ${groupId}.${artifactId} 新增配置文件

reflect-config.json: 反射配置

serialization-config.json: 序列化配置

proxy-config.json: 动态代理配置

resource-config.json: 外部文件配置

1.2.3.4.5.1.2.3.4.5.

复制

4. 常见问题

4.1 构建问题

4.1.1 在构建时意外初始化了 DataSize

Error: Classes that should be initialized at run time got initialized during image building:

org.springframework.util.unit.DataSize was unintentionally initialized at build time. To see why org.springframework.util.unit.DataSize got initialized use --trace-class-initialization

1.2.1.2.

复制

缺乏 spring-native 依赖项和Spring AOT plugin

4.1.2 构建本机映像时出现内存不足错误

Error: Image build request failed with exit status 137。native-image 会消耗大量 RAM,因此建议您使用至少 16G RAM 的计算机

4.1.3 Builder 生命周期 ‘creator’ 失败,状态码为 145

Error: Image build request failed with exit status 145。内存不足, 网络问题等

4.1.4 缺少资源包

Caused by: java.util.MissingResourceException:

 Resource bundle not found javax.servlet.http.LocalStrings.

 Register the resource bundle using the option

   -H:IncludeResourceBundles=javax.servlet.http.LocalStrings.

1.2.3.4.1.2.3.4.

复制

4.2 运行问题

4.2.1 序列化&反序列化失败问题

反序列化失败

DemoResponse(data=null, code=null, message= null)

序列化失败

在 META-INF/native-image/${groupId}/${artifactId}/serialization-config.json 添加需要进行序列化的类信息

[

{

  "name": "com.springnative.demo.response.DemoResponse"

}

]

1.2.3.4.5.6.7.8.9.1.2.3.4.5.6.7.8.9.

复制

4.2.2 反射问题

在 META-INF/native-image/${groupId}/${artifactId}/reflect-config.json 中添加需要用到反射的类信息

{

 "name": "com.springnative.demo.response.DemoResponse",

 "allDeclaredFields": true,

 "allDeclaredConstructors": true,

 "allDeclaredMethods": true,

 "allPublicMethods": true,

 "allDeclaredClasses": true

}

1.2.3.4.5.6.7.8.9.1.2.3.4.5.6.7.8.9.

复制

4.2.3 apache httpclient 调用失败, 采用 java.net.http.HttpClient 替换

4.2.4 mybatis-plus 初始化问题 & mapper 失效问题 (待补充)

5. 参考资料

Spring Native documentationGraalvmgraalvm-ce-buildsSpring-native Githubpaketo

相关文章
|
1月前
|
运维 Cloud Native 持续交付
深入理解云原生架构及其在现代企业中的应用
随着数字化转型的浪潮席卷全球,企业正面临着前所未有的挑战与机遇。云计算技术的迅猛发展,特别是云原生架构的兴起,正在重塑企业的IT基础设施和软件开发模式。本文将深入探讨云原生的核心概念、关键技术以及如何在企业中实施云原生策略,以实现更高效的资源利用和更快的市场响应速度。通过分析云原生架构的优势和面临的挑战,我们将揭示它如何助力企业在激烈的市场竞争中保持领先地位。
|
1月前
|
运维 Cloud Native 安全
云原生技术在现代企业中的应用与挑战####
本文探讨了云原生技术在现代企业IT架构中的关键作用,分析了其带来的优势和面临的主要挑战。通过实际案例分析,揭示了如何有效应对这些挑战,以实现业务敏捷性和技术创新的平衡。 ####
|
1月前
|
Cloud Native 持续交付 开发者
云原生技术在现代企业中的应用与实践####
本文深入探讨了云原生技术的核心概念及其在现代企业IT架构转型中的关键作用,通过具体案例分析展示了云原生如何促进企业的敏捷开发、高效运维及成本优化。不同于传统摘要仅概述内容,本部分旨在激发读者对云原生领域的兴趣,强调其在加速数字化转型过程中的不可或缺性,为后续详细论述奠定基础。 ####
|
1月前
|
Kubernetes Cloud Native 物联网
云原生技术在现代软件开发中的应用与挑战####
本文探讨了云原生技术的兴起背景、核心理念及其在现代软件开发中的广泛应用。通过具体案例分析,揭示了云原生架构如何促进企业数字化转型,并指出了在实施过程中面临的主要挑战及应对策略。 ####
|
1月前
|
人工智能 缓存 异构计算
云原生AI加速生成式人工智能应用的部署构建
本文探讨了云原生技术背景下,尤其是Kubernetes和容器技术的发展,对模型推理服务带来的挑战与优化策略。文中详细介绍了Knative的弹性扩展机制,包括HPA和CronHPA,以及针对传统弹性扩展“滞后”问题提出的AHPA(高级弹性预测)。此外,文章重点介绍了Fluid项目,它通过分布式缓存优化了模型加载的I/O操作,显著缩短了推理服务的冷启动时间,特别是在处理大规模并发请求时表现出色。通过实际案例,展示了Fluid在vLLM和Qwen模型推理中的应用效果,证明了其在提高模型推理效率和响应速度方面的优势。
云原生AI加速生成式人工智能应用的部署构建
|
1月前
|
Cloud Native JavaScript Docker
云原生技术:构建现代应用的基石
在数字化转型的浪潮中,云原生技术如同一艘承载梦想的航船,引领企业驶向创新与效率的新海域。本文将深入探索云原生技术的核心价值,揭示其如何重塑软件开发、部署和运维模式,同时通过一个简易代码示例,展现云原生应用的构建过程,让读者领略到云原生技术的魅力所在。
|
2月前
|
消息中间件 Cloud Native 持续交付
云原生技术在现代企业中的应用与优势###
本文深入探讨了云原生技术在现代企业中的具体应用及其带来的显著优势。随着云计算的普及,云原生作为一种新兴的技术架构,正逐渐成为企业数字化转型的关键驱动力。文章将详细介绍云原生的核心概念、主要技术组件以及在实际业务场景中的成功案例,旨在为读者提供一个全面且实用的参考框架,以便更好地理解和应用云原生技术。 ###
|
2月前
|
Cloud Native 持续交付 云计算
深入理解云原生技术及其在现代IT架构中的应用
在数字化浪潮的推动下,云原生技术已成为企业转型的关键。本文将通过浅显易懂的语言和生动的比喻,带领读者探索云原生的核心概念、优势以及如何在企业中实现云原生架构。我们将一起揭开云原生的神秘面纱,了解它如何助力企业快速适应市场变化,提升业务的灵活性和创新能力。
|
2月前
|
Cloud Native JavaScript Devops
云原生技术在现代软件开发中的应用与实践
本文将深入探讨云原生技术如何改变现代软件开发的格局。通过分析云原生的核心概念、优势以及在实际开发中的应用案例,我们将了解这一前沿技术如何助力企业快速适应市场变化,提高开发效率和系统稳定性。文章还将提供实用的代码示例,帮助开发者更好地理解和运用云原生技术。
|
2月前
|
Kubernetes Cloud Native Devops
云原生技术在现代软件开发中的应用与挑战####
云原生,这一词汇如同云计算浪潮中的灯塔,引领着技术革新的方向。本文旨在探讨云原生技术的核心概念、关键组件及其在现代软件开发中的实践应用,同时剖析面临的挑战与应对策略。通过深入分析Kubernetes、微服务架构、DevOps文化等要素,揭示云原生如何赋能企业实现高效、弹性的IT系统构建,并展望其未来发展趋势。 ####
25 0