我把Solon打包成了native image,速度快的惊人

news2025/6/18 4:06:06

Solon 一个高效的应用开发框架:更快、更小、更简单。https://solon.noear.org/

我刚开始对 Solon 感兴趣的原因,就是启动快、包体积小,用了一段时间之后,发现 Solon 使用 GraalVM native iamge 打包有一些问题,我把问题发到 Solon 用户群里,作者告诉我 Solon 的原生编译还 beat 阶段,只做了一部分,问我有没有兴趣,然后我就一边研究 GraalVM naitve image 规范,一边看 Spring 的源码,看看前辈们是怎么实现的,到今天终于在 Solon 上有了阶段性的进展。






启动耗时13ms,内存占用13.5MB(不同机器启动时间会有所差异)

示例源码地址:https://github.com/dudiao/solon-native-example

什么是 Solon AOT ?

AOT 是 Ahead-Of-Time 的简写,指运行前编译,与之对应的是 JIT,即 Just-In-Time,即时(动态)编译,边运行边编译。


Solon AOT 实际上是指 Solon AOT 优化,帮助 GraalVM 更好的将 Solon 应用编译为本机可执行程序(native image),大体思路是构建时,检查应用上下文,找到被使用的类、方法、字段等,并做出相应的决策。做到这些,需要在构建时启动应用,才能获取到上下文 AopContext,Solon AOT 在处理中,可能会生成:

  • Java 类(通常是动态代理)
  • RuntimeNativeMetadata 运行时元数据,包括反射,资源,序列化等
  • Solon 运行时元数据

使用方式

1. 增加solon.aot和solon.apt依赖

<!--solon native start-->
<!--aot 注册native元信息-->
<dependency>
  <groupId>org.noear</groupId>
  <artifactId>solon.aot</artifactId>
</dependency>
<!-- apt 生成代理类 -->
<dependency>
  <groupId>org.noear</groupId>
  <artifactId>solon.proxy.apt</artifactId>
  <scope>provided</scope>
</dependency>
<!--solon native end-->

2. 注册需要的运行时元数据(可选)

比如 User 类需要序列化,可以这样注册:

@Component
public class MyNativeRegistrar implements RuntimeNativeRegistrar {

  @Override
  public void register(AopContext context, RuntimeNativeMetadata nativeMetadata) {
    nativeMetadata.registerSerialization(User.class);
  }
}

实现RuntimeNativeRegistrar接口,且实现类需要是一个solon bean。

3. 生成为本机可执行程序(native image)

环境要求:graalvm 17 & native-image
如果你的项目中使用solon-parent来管理依赖,比如:

<parent>
    <groupId>org.noear</groupId>
    <artifactId>solon-parent</artifactId>
    <version>2.2.13-SNAPSHOT</version>
    <relativePath />
</parent>

<groupId>com.dudiao.solon</groupId>
<artifactId>solon-native-example</artifactId>
<version>1.0</version>

直接使用如下命令打包为 native image

mvn clean native:compile -P native

如果你的项目中没有使用solon-parent,可以在pom.xml中增加:

<profiles>
  <profile>
    <id>native</id>
    <build>
      <plugins>
        <plugin>
          <groupId>org.noear</groupId>
          <artifactId>solon-maven-plugin</artifactId>
          <version>${solon.version}</version>
          <executions>
            <execution>
              <id>process-aot</id>
              <goals>
                <goal>process-aot</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
        <plugin>
          <groupId>org.graalvm.buildtools</groupId>
          <artifactId>native-maven-plugin</artifactId>
          <version>${native.version}</version>
          <!-- 使用graalvm提供的可达性元数据,很多第三方库就直接可以构建成可执行文件了 -->
          <configuration>
            <metadataRepository>
              <enabled>true</enabled>
            </metadataRepository>
          </configuration>
          <executions>
            <execution>
              <id>add-reachability-metadata</id>
              <goals>
                <goal>add-reachability-metadata</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

同样使用mvn clean native:compile -P native即可打包为本机可执行程序。

也可以参考 solon native 的示例项目:
https://github.com/dudiao/solon-native-example

实现原理


Solon AOT的总体思路是:

  1. 编译时,通过 apt 生成代理类(之后这部分逻辑会迁移到 solon-maven-plugin 中);
  2. Maven 构建时,增加ProcessAotMojo,用来收集应用的依赖包,通过 java -cp 命令调用SolonAotProcessor
  3. SolonAotProcessor中,会先反射执行应用主类(标记@SolonMain注解),获取到应用上下文;
  4. 注册AopContext中的 BeanWrap(应用中所有的bean)、MethodWrap(方法包装)到运行时元数据中;注册所有插件(PluginEntity)到元数据中;
  5. 用户手动注册到运行时元数据,实现 RuntimeNativeRegistrar 接口;
  6. 生成GraalVM Reachability Metadata(可达性元数据),包含:native-image.properties、resource-config.json、reflect-config.json、serialization-config.json。同时还会生成Solon元数据文件 solon-resource.json,用于在 native 环境中,扫描某个 resource 目录下的资源。

注意事项

通过静态编译构建的二进制程序,虽然有内存占用小,启动速度快的优点,但也有一些局限性,比如不能在运行时获取某个类的所有方法、获取所有 resource 资源。

Solon 正尝试另外一种方式来间接实现:通过在 AOT 阶段生成的元数据文件:reflect-config.jsonsolon-resource.json,运行时读取这两个文件,reflect-config.json包含了类和字段的信息,solon-resource.json中包含了resource目录下的资源信息。

可以通过工具类ReflectUtil获取类上所有字段和方法,工具类ScanUtil扫描路径下的所有资源。

最后

Solon + GraalVM native image 无论是启动速度,还有内存占用,都让我眼前一亮,如果你不了解 Solon,可以试一试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/426683.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cache;高速缓冲存储器

高速缓冲存储器 概述 ​ 在多体并行存储系统中&#xff0c;由于IO设备向主存请求的级别高于CPU访存&#xff0c;这就出现了CPU等待IO设备访存的现象&#xff0c;导致CPU空等一段时间&#xff0c;甚至等待几个周期&#xff0c;从而降低了CPU的工作效率&#xff0c;为了避免CPU…

Eclipse环境搭建并且运行wordcount程序

一、安装Hadoop插件 1. 所需环境 hadoop2.0伪分布式环境平台正常运行 所需压缩包&#xff1a;eclipse-jee-luna-SR2-linux-gtk-x86_64.tar.gz           在Linux环境下运行的eclipse软件压缩包,解压后文件名为eclipse           hadoop2x-eclipse-plugin-m…

【Mysql】事物处理(TransAction Processing)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶最近在复习mysql&#xff0c;复习到了mysql事物处理&#xff08;TransAction&#xff09;&#xff0c;帮自己回顾一下&#xff0c;如果你也想了解什么是mysql的事物处理&#xff0c;希望这篇…

【SQL Server】无需公网IP,就可以远程连接SQL Server数据库

目录 1.前言 2.本地安装和设置SQL Server 2.1 SQL Server下载 2.2 SQL Server本地连接测试 2.3 Cpolar内网穿透的下载和安装 2.3 Cpolar内网穿透的注册 3.本地网页发布 3.1 Cpolar云端设置 3.2 Cpolar本地设置 4.公网访问测试 5.结语 1.前言 数据库的重要性相信大家…

基于html+css的自适应展示3

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

MySQL--库的操作--校验规则对于数据库的影响--0409

目录 1.库的基础操作 查看数据库 创建数据库 删除数据库 查看建库语句 修改数据库 2.字符集和字符集校验规则 2.1 查看系统默认字符集以及校验规则 2.2 使用特定的字符集创建数据库 2.3 不同校验规则对数据库的影响 2.3.1 大小写验证 2.3.2 排序验证 3.备份和恢复 3.1…

开启单细胞及空间组学行业发展黄金时代!首届国际单细胞及空间组学大会在穗闭幕

2023年4月16日&#xff0c;首届TICSSO国际单细胞及空间组学大会圆满闭幕&#xff0c;本次大会吸引了2000余位来自产、学、研、资、医、政、媒等业界人士齐聚羊城&#xff0c;注册总人数5398人&#xff0c;网络播放总量达548245人次&#xff0c;网络观看覆盖美国、德国、日本、澳…

Vue语法糖<script setup>详解,用最快的方式让你看懂和<script>的区别

前言 Vue3出来已经3年了&#xff0c;但是前两天在百度上搜索有关setup语法糖的细节时&#xff0c;发现很多博客关于语法糖细节部分&#xff0c;还是讲的很粗糙&#xff0c;因此决定自己来写一篇入门的博客&#xff0c;方便大家快速上手。 <script setup>简介 它是Vue3…

关于ASP.NET MVC与.NET CORE 的区别--小结

简述关于ASP.NET MVC与.NET CORE的区别 1、关于ASP.NET 关于MVC 刚开始接触这个技术的时候我经常不理解他们的名字&#xff0c;我相信许多学ASP.NET开发人员开始接触MVC应该也和我一样产生很多为什么&#xff0c;也会误认为认为MVC与ASP.NET完全没有关系&#xff0c;是一个全新…

基于ssm+vue的学生实习过程管理系统

基于ssmvue的学生实习过程管理系统 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍…

Kotlin与H5通信的实现方式

Kotlin与H5通信1、H5中主动的调用Kotlin中的程序1编写后端程序并且在服务器上运行2准备好AndroidStudio的界面布局中的WebView3编写工具类用来处理H5调用逻辑4通过addJavascriptInterface来构建桥梁5结果展示2在Kotlin中调用H5的程序1在H5中编写方法&#xff0c;来处理Kotlin的…

【C】Operator / Expression

系列连载 【python / C / C】 参考 《C语言程序设计&#xff08;第四版&#xff09;谭浩强》【C语言】C语言视频教程《郝斌 C 语言自学教程》 文章目录1 运算符1.1 基本的算术运算符2 表达式1 运算符 1.1 基本的算术运算符 注意&#xff0c; 是右结合的 “” 具有左结合性&…

C++ 面向对象、多继承

// Student.hclass Student { private: // 私有的&#xff0c;外界不能访问char *name;int age;public:void setAge(int age);void setName(char* name);int getAge();char* getName();// 空参构造函数Student(){}// 一参构造函数Student(char* name) : Student(name,80) {// 调…

干翻Hadoop系列:MapReduce详解

第一章&#xff1a;MapReduce原理 数据存储在分布式文件系统中HDFS里边&#xff0c;通过使用Hadoop资源管理系统YARN&#xff0c;Hadoop可以将MapReduce计算&#xff0c;转移到有存储部分的数据的各台机器上。 一&#xff1a;概念和原理 1&#xff1a;MapReduce作业 MapRed…

【机器学习】P16 激活函数 Activation Function

对于激活函数&#xff08;Activation Function&#xff09;&#xff0c;存在两个问题&#xff1a; 为什么要用激活函数&#xff1f;如何选择用哪种激活函数&#xff1f;如何使用激活函数&#xff1f; 本博文将围绕这两个问题&#xff0c;首先介绍激活函数的作用&#xff0c;从…

2023腾讯云轻量应用服务器性能评测

腾讯云轻量应用服务器性能如何&#xff1f;CPU型号主频、内存、公网带宽和系统盘存储多维对比&#xff0c;轻量应用服务器会不会比云服务器CVM性能差&#xff1f;相对于CVM云服务器轻量服务器更适合轻量级的应用&#xff0c;轻量服务适合中小企或个人开发者用于搭建We网站b应用…

利用Python生成和识读二维码(QR Code)和微二维码(Micro QR Code)

目录一、环境准备二、二维码&#xff08;QR Code&#xff09;生成和读取2.1 生成二维码2.2 读取二维码三、微二维码&#xff08;Micro QR Code&#xff09;生成和读取3.1 生成微二维码3.2 读取微二维码之前写的一篇 博客采用了segno库来做微二维码的生成&#xff0c;该库可以方…

AD9689 input clock not detect

在项目调试中&#xff0c;遇到的问题&#xff0c;在ADI论坛上发帖咨询&#xff0c;转发到这里。网址如下&#xff1a; AD9689 input clock not detect - Q&A - High-Speed ADCs - EngineerZone (analog.com) Our FPGA board has two AD9689&#xff0c;one works ok, but…

使用Marshaller 将Java对象转化为XML格式和字符串转为xml

使用Marshaller 将Java对象转化为XML格式 对象转xml内容 ①工具类 public static String convertObjectToXml(Object obj) throws Exception {StringWriter writer new StringWriter();// 创建 JAXBContext 和 MarshallerJAXBContext context JAXBContext.newInstance(obj.ge…

MySQL客观题

MySQL客观题 在数据库的三级模式结构中&#xff0c;描述数据库中全体数据的全局逻辑结构和特性的是&#xff08; A &#xff09; A 模式 B 内模式 C 存储模式 D 外模式 数据库系统的特点是&#xff08; A &#xff09;、数据独立、减少数据冗余、避免数据不一致和加强了数据保…