今天带你体验79毫秒启动一个SpringBoot项目

2023-11-05

大家好,我是雷小帅,今天来个项目实战。

先抛一个问题,大家在自己电脑上启动一个 spring boot 项目需要花费多久?

根据项目大小和机器环境,花费几秒到几十秒的人应该都有。

最近 spring 官方推出了一项技术可以将项目的启动时间缩短到 79 毫秒,79 毫秒大概是个什么概念?就是你还没反应过来项目已经启动好了,太牛了。

这项技术被 spring 官方命名为Spring Native,翻译成中文叫Spring 云原生,应该有少部分人听说过这个概念,我先带大家入门扫盲。

我是谁?

Spring Native 是 Spring 推出微服务体系 Spring Cloud 之后的又一大举动,从名字可以猜出,Spring Native是一门面向云原生的技术。如果你还对这个概念不太理解,可以多看一点东西,比如 Oracle 的 GraalVM等。

Spring Native 为使用 GraalVM 原生镜像编译器编译 Spring 应用为本地可执行文件提供支持。与 Java 虚拟机相比,原生镜像可以在许多场景下降低工作负载,包括微服务,函数式服务,非常适合容器和 Kubernetes。使用原生镜像有明显优势,如快速启动,提高峰值性能以及降低内存消耗。

我有多强

上面提到了原生镜像,简单来说原生镜像是一种将Java代码提前编译为独立可执行文件(称为本机映像)的技术。可执行文件包括应用程序类,以及其依赖项的类,运行时库类以及JDK中的静态链接本机代码。

小芝士,GraalVM官网对原生镜像的解释:

原生镜像提供了一种构建和运行具有不同于常规JVM部署特性的Spring Boot应用程序的方法:

  • 输出是一个本机可执行文件,其中包含您的应用程序以及JDK的子集以及运行它所需的依赖项。
  • 在实践中,可执行文件可能会以高度优化的容器映像(FROM scratch支持Docker镜像)的形式提供,并且减少了表面攻击,非常适合Kubernetes。
  • 启动时间几乎是即时的,并且可以立即获得峰值性能,从而支持从零缩放(无服务器)应用程序,包括常规的Spring Boot Web应用程序。
  • 减少了内存消耗,这非常适合拆分为多个微服务的系统。

这些原生的 Spring 应用可以作为一个独立的可执行文件(原生镜像)进行部署(不需要安装 JVM),性能非常强:

  • 几乎瞬时的启动(一般会小于 100 毫秒)
  • 瞬时的峰值性能以及更低的资源消耗

当然牛逼的背后肯定要稍微付出一点代价:比 JVM 更长的构建时间和更少的运行时优化。

上手

既然 Spring Native 性能这么强悍,是不是得动手试一试了。

下面我会拿传统的 springboot 项目和基于 Spring Native的项目进行比较演示。

环境信息

  • 电脑:MacBook pro 13寸 2017
  • 操作系统:macOS Big Sur 11.2
  • IDE:IntelliJ IDEA 2021.2.2 (Ultimate Edition)
  • Open JDK:11.0.12
  • maven:3.6.3
  • Docker desktop:4.0.1

初始化项目

进入 spring 初始化页面:

https://start.spring.io/

第一步:填写必要项目信息

这里我选择 maven 构建,spring boot 版本选择 2.5.8,jdk 版本选择 11

第二步:添加必要依赖

添加两个依赖:

  • spring native
  • spring web

第三步:生成项目骨架代码

点击下载可以获得一个压缩包

注意:以上步骤也可以直接在 IDEA 里通过 start.spring.io进行新建,这里不再赘述。

运行项目

导入测试项目后可以在根目录下面看到一个帮助文档:

通过阅读帮助文档得知有两种方式启动 spring native 项目:

  • 第一种:借助 maven 插件将项目构建为 docker 镜像,然后启动镜像;
  • 第二种:借助本地构建工具将项目打包为一个可执行的文件,然后直接启动即可。

我电脑上已经装了 docker 工具,这里我演示一下第一种方式。

第一步:生成docker 镜像文件

$ ./mvnw spring-boot:build-image

这个过程可能有点漫长,也可能会失败,大家做好心理准备。

第二步:启动镜像文件

$ docker run --rm spring-native-demo:0.0.1-SNAPSHOT

执行完命令之后,项目瞬间就跑起来了。

性能测试对比

场景一:使用 Spring Native

官方宣称 79 毫秒就可以启动,原谅我的电脑太渣了,最好的一次花费了 143 毫秒,也就是一瞬间的事情,确实牛叉。

image-20220118001729343

场景二:普通启动

没有对比就没有伤害,普通启动花费了2.091 秒

image-20220118002006136

结论

在我的破电脑上测试,Spring Native 的启动速度大致是普通启动的 15 倍。

Spring Native 牛逼!牛逼!牛逼!(破音)

FAQ

在测试过程中踩了不少坑,这里做一个汇总。

问题一:maven 依赖下载失败,网络差

可以配置 maven 镜像仓库

<mirror>
  <id>aliyunmaven</id>
  <mirrorOf>*</mirrorOf>
  <name>central</name>
  <url>https://maven.aliyun.com/repository/central</url>
</mirror>

问题二:镜像构建失败,提示内存不足

解决方法:增大 Docker 的内存配置


好了,以上就是今天全部的内容,大家学会了吗?我是雷小帅,每天带你进步一点点~

如果你觉得很赞,欢迎点赞支持一下,很需要你们的正反馈!

更多技术干货(拼命更新中,欢迎催更……)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

今天带你体验79毫秒启动一个SpringBoot项目 的相关文章

  • 当路径的点超出视野时,Android Canvas 不会绘制路径

    我在绘制路径时遇到了 Android Canvas 的一些问题 我的情况是 我有一个相对布局工作 如地图视图 不使用 google api 或类似的东西 我必须在该视图上绘制一条路径 canvas drawPath polyPath bor
  • Base36 编码字符串?

    我一直在网上查找 但找不到解决此问题的方法 在 Python Ruby 或 Java 中 如何对以下字符串进行 Base 36 编码 nOrG9Eh0uyeilM8Nnu5pTywj3935kW 5 Ruby 以 36 为基数 s unpa
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List
  • Android 中 localTime 和 localDate 的替代类有哪些? [复制]

    这个问题在这里已经有答案了 我想使用从 android API 获得的长值 该值将日期返回为长值 表示为自纪元以来的毫秒数 我需要使用像 isBefore plusDays isAfter 这样的方法 Cursor managedCurso
  • Java:从集合中获取第一项

    如果我有一个集合 例如Collection
  • 是否可以从 servlet 内部以编程方式设置请求上下文路径?

    这是一个特殊情况 我陷入了处理 企业 网络应用程序的困境 企业应用程序正在调用request getContext 并将其与另一个字符串进行比较 我发现我可以使用 getServletContext getContextPath 获取 se
  • 从直方图计算平均值和百分位数?

    我编写了一个计时器 可以测量任何多线程应用程序中特定代码的性能 在下面的计时器中 它还会在地图中填充花费了 x 毫秒的调用次数 我将使用这张图作为我的直方图的一部分来进行进一步的分析 例如调用花费了这么多毫秒的百分比等等 public st
  • 在 Java 中通过 XSLT 分解 XML

    我需要转换具有嵌套 分层 表单结构的大型 XML 文件
  • 我们如何测试包私有类?

    我正在看书Effective Java in Item 13 Minimize the accessibility of classes and members 它提到 为了方便测试 您可能想让类 接口或成员更易于访问 这在某种程度上是好的
  • 寻找局部最小值

    下面的代码正确地找到了数组的局部最大值 但未能找到局部最小值 我已经进行了网络搜索 以找到找到最小值的最佳方法 并且根据这些搜索 我认为我正在使用下面的正确方法 但是 在几天的时间里多次检查每一行之后 下面的代码中有一些我仍然没有看到的错误
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • 如何停止执行的 Jar 文件

    这感觉像是一个愚蠢的问题 但我似乎无法弄清楚 当我在 Windows 上运行 jar 文件时 它不会出现在任务管理器进程中 我怎样才能终止它 我已经尝试过 TASKKILL 但它对我也不起作用 On Linux ps ef grep jav
  • Karaf / Maven - 无法解决:缺少需求 osgi.wiring.package

    我无法在 Karaf 版本 3 0 1 中启动捆绑包 该包是使用 Maven 构建的并导入gson http mvnrepository com artifact com google code gson gson 2 3 1 我按照要求将
  • 避免 Java 中的重复导入:继承导入?

    有没有办法 继承 导入 Example 常见枚举 public enum Constant ONE TWO THREE 使用此枚举的基类 public class Base protected void register Constant
  • 如何从 Spring Boot 中排除依赖项

    我正在使用 Spring Boot 以下是我的 gradle 文件 buildscript ext springBootVersion 2 0 0 BUILD SNAPSHOT repositories mavenCentral maven
  • 如何处理 StaleElementReferenceException

    我正在为鼠标悬停工作 我想通过使用 for 循环单击每个链接来测试所有链接的工作条件 在我的程序中 迭代进行一次 而对于下一次迭代 它不起作用并显示 StaleElementReferenceException 如果需要 请修改代码 pub
  • 替换文件中的字符串

    我正在寻找一种方法来替换文件中的字符串而不将整个文件读入内存 通常我会使用 Reader 和 Writer 即如下所示 public static void replace String oldstring String newstring
  • JMS 中的 MessageListener 和 Consumer 有什么区别?

    我是新来的JMS 据我了解Consumers能够从队列 主题中挑选消息 那么为什么你需要一个MessageListener因为Consumers会知道他们什么时候收到消息吗 这样的实际用途是什么MessageListener 编辑 来自Me
  • Java 的 PriorityQueue 与最小堆有何不同?

    他们为什么命名PriorityQueue如果你不能插入优先级 它看起来与堆非常相似 有什么区别吗 如果没有区别那为什么叫它PriorityQueue而不是堆 默认的PriorityQueue是用Min Heap实现的 即栈顶元素是堆中最小的
  • HttpClient请求设置属性问题

    我使用这个 HttpClient 库玩了一段时间 几周 我想以某种方式将属性设置为请求 不是参数而是属性 在我的 servlet 中 我想使用 Integer inte Integer request getAttribute obj 我不

随机推荐

  • 【Linux】几种典型的IO模型

    几种典型的IO模型 常见IO场景 输入和输出 读写文件 read write fread fwrite 网络接收与发送 send recv sendto recvfrom 上述两种场景都有一个共同点 就是最终都会和操作系统打交道 IO过程
  • python高级特性总结之切片 迭代 生成器 迭代器

    切片 gt gt gt L list range 100 gt gt gt L 0 1 2 3 99 gt gt gt L 10 0 1 2 3 4 5 6 7 8 9 gt gt gt L 10 90 91 92 93 94 95 96
  • PlantCV 农业自动化中的机器视觉库

    PlantCV 农业自动化中的机器视觉库 2020年下半年 各大互联网巨头纷纷进军社区买菜市场 我身边的朋友同事很多都开始通过新的电商生鲜渠道购买蔬菜 当时我就觉得 大资本即将涌入我们的第一产业 农业 果不其然 2020年12月31号 正值
  • Dell PowerEdge R740xd解析:服务器只看参数那就错了

    昨天写了 Dell PowerEdge R940解析 四路顶配服务器维护平民化 今天继续 对于R7x0这样的2U主力服务器机型 说实话我觉得不是特别好写 一方面不如四路有特点 另外又是互联网等行业消耗最多的 可以说乃服务器厂商必争之地 正如
  • Ubuntu下安装Chrome浏览器

    一 下载包 通过直接下载安装Google Chrome浏览器deb包 打开Ubuntu终端 以下为32位版本 使用下面的命令 wget https dl google com linux direct google chrome stabl
  • 模拟相机视频输入方案-----模拟转MIPI /DVP方案

    技术交流 请加微信video D 概述 由于模拟相机在监控领域的优势 以及模拟相机成本优势 目前模拟相机方案需求还是很多的 具体模拟解码芯片介绍 目前接触的有以下几种 1 Nextchip系列 韩国NEXTCHIP系列 主攻ISP AHD
  • 开发微信公众号支付代码

    一 url传入当前页面url地址或者微信公众平台配置的域名根目录 使用window location href方法获取 二 下面代码请结合微信公众号开发文档 微信公众号开发文档 function test url uni request u
  • 如何在Linux下安装vim编辑器

    目前的Ubuntu版本都安装了vi编辑器 vim编辑器可以看做vi编辑器的升级版 可以识别特殊字符 显示不同颜色 目录 第一步 第二步 第三步 第四步 第一步 在terminal里面输入vi命令后按下tab键可以看到当前vi可以执行的命令
  • 算法的时间及空间复杂度

    简介 java系列技术分享 持续更新中 初衷 一起学习 一起进步 坚持不懈 如果文章内容有误与您的想法不一致 欢迎大家在评论区指正 希望这篇文章对你有所帮助 欢迎点赞 收藏 留言 更多文章请点击 文章目录 一 什么是算法 二 算法初体验 案
  • C++ String替换&分割指定字符串

    C String替换 分割指定字符串 1 C String替换指定字符串 C 的string对象提供了replace方法来实现字符串的替换 本文实现对于将字符串中某个字符串全部替换的功能 string replace all string
  • MOOC清华《程序设计基础》第5章:求n的阶乘(用递推法做)

    使用递推思想 求解正整数的阶乘 本算法的数学模型为 n n 1 n include
  • CCF CSP 202206-3角色授权【70分】

    include
  • ts文件服务器端加密,加密ts文件解密

    EXTM3U EXT X VERSION 3 EXT X MEDIA SEQUENCE 0 EXT X ALLOW CACHE YES EXT X TARGETDURATION 13 EXT X KEY METHOD AES 128 URI
  • Linux动态库(.so)搜索路径

    Linux动态库 so 搜索路径 众所周知 Linux动态库的默认搜索路径是 lib和 usr lib 动态库被创建后 一般都复制到这两个目录中 当程序执行时需要某动态库 并且该 动 态库还未加载到内存中 则系统会自动到这两个默认搜索路径中
  • 网站无法访问的一些问题与解决

    最近阿里云的服务器上跑的博客出现了一些问题 上阿里云官网看了一下 原来是忘记续费了 也没给我发邮件 悄摸的给我停了 续费之后 问题依旧 可以使用xshell5进行远程连接 但是在浏览器上不能进行访问 会显示这个 很尴尬 在本地ping主机是
  • cuda异步并行执行

    异步函数使得主机端与设备端并行执行 控制在设备还没有完成前就被返回给主机线程 包括 kernel启动 以Async为后缀的内存拷贝函数 device到device内存拷贝函数 存储器初始化函数 比如cudaMemset cudaMemset
  • simulink中积分环节、惯性环节、比例环节

    第一步 第二步 第三步 注 适当修改参数即可变成所需环节 如下所示 修改为 或者为 抑或
  • hadoop搭建好,启动服务后,无法从web界面访问50070

    在hadoop完全分布式搭建好以后 从主节点启动正常 使用jps查看启动的进程 正常 在几个从节点上使用jps查看 显示正常 但从web上输入下面网址 http 主节点IP 50070 无法正常连接显示 试了若干网上查到的方法 是通过下面方
  • 怎样选择合适的循环体(do&while、while和for)

    我们都知道 循环体可以有五种 while do while for goto和递归 虽然理论上任何循环都可以用其他四种转换 但是因为goto在安全性以及在功能上能够被取代的特点 所以一般不会用到 而递归的特殊性和编写的困难性使递归的登场次数
  • 今天带你体验79毫秒启动一个SpringBoot项目

    大家好 我是雷小帅 今天来个项目实战 先抛一个问题 大家在自己电脑上启动一个 spring boot 项目需要花费多久 根据项目大小和机器环境 花费几秒到几十秒的人应该都有 最近 spring 官方推出了一项技术可以将项目的启动时间缩短到