微服务架构之争:Quarkus VS Spring Boot
在容器时代(“Docker时代”),无论如何,Java仍然活着。Java在性能方面一直很有名,主要是因为代码和真实机器之间的抽象层,多平台的成本(一次编写,随处运行——还记得吗?),中间有一个JVM(JVM:模拟真实机器的软件机器)。
如今,有了微服务架构,也许它不再有意义,也没有任何优势,为总是在同一地方和平台上运行的东西(Docker 容器 — Linux 环境)构建多平台(解释)的东西。可移植性现在不那么重要了(也许比以往任何时候都更重要),那些额外的抽象级别并不重要。
话虽如此,让我们对在 Java 中生成微服务的两种替代方案进行简单而原始的比较:非常著名的 Spring Boot 和不太知名的 Quarkus。
对手
Quarkus
一套适用于GraalVM和HotSpot的开源技术,用于编写Java应用程序。它提供(承诺)超快的启动时间和更低的内存占用。这使其成为容器和无服务器工作负载的理想选择。它使用 Eclipse Microprofile(JAX-RS、CDI、JSON-P)来构建微服务,这是 Java EE 的一个子集。
GraalVM 是一个通用的多语言虚拟机(JavaScript、Python、Ruby、R、Java、Scala、Kotlin)。 GraalVM(特别是 Substrate VM)使提前 (AOT) 编译成为可能,将字节码转换为本机机器码,从而生成可以在本机执行的二进制文件。
请记住,并非每个功能在本机执行中都可用,AOT 编译有其局限性。注意这句话(引用GraalVM团队的话):
我们运行一个积极的静态分析,它需要一个封闭世界的假设,这意味着在运行时可以访问的所有类和所有字节码都必须在构建时是已知的。
因此,例如,反射和 Java 本机接口 (JNI) 将不起作用,至少是开箱即用的(需要一些额外的工作)。您可以在此处找到限制列表本机映像 Java 限制文档。
Spring Boot
不用多介绍了,用一句话说(随意跳过它):Spring Boot 建立在 Spring Framework 之上,是一个开源框架,它提供了一种更简单的方法来构建、配置和运行基于 Java Web 的应用程序。使其成为微服务的良好候选者。
战斗准备 — 创建 Docker 镜像
Quarkus 镜像
让我们创建 Quarkus 应用程序,稍后将其包装在 Docker 映像中。基本上,我们将执行与Quarkus入门教程相同的操作。
使用 Quarkus maven 原型创建项目:
mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR2:create \ -DprojectGroupId=ujr.combat.quarkus \ -DprojectArtifactId=quarkus-echo \ -DclassName="ujr.combat.quarkus.EchoResource" \-Dpath="/echo"
这将项目的结构,如下所示:
请注意,还创建了两个示例 Dockerfile (src/main/docker):一个用于普通 JVM 应用程序映像,另一个用于本机应用程序映像。
在生成的代码中,我们只需要更改一件事,添加下面的依赖项,因为我们想要生成 JSON 内容。
<dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
Quarkus 在整个 RESTEasy 项目实现中使用 JAX-RS 规范。
这是我们的“完整”应用程序:
仅此而已,通过下一个命令,我们可以看到应用程序正在运行:
mvn clean compile quarkus:dev
在这种模式下,我们还启用了热部署,并带有后台编译。让我们做一个简单的测试来看看它:
curl -sw "\n\n" http://localhost:8080/echo/ualter | jq .
现在我们已经看到它正在工作,让我们创建 Docker 映像。从此处下载 GraalVM:Releases · graalvm/graalvm-ce-builds · GitHub。
重要! 不要下载最新版本 19.3.0, Quarkus 1.0 它与它不兼容,也许 Quarkus 1.1 会。现在应该可以运行的版本是 GraalVM 19.2.1,获取这个版本。
配置其环境变量主路径:
## At macOS will be: export
GRAALVM_HOME=/Users/ualter/Developer/quarkus/graalvm-ce-java8-19.2.1/Contents/Home/
然后在您的环境中安装 GraalVM 的本机映像:
$GRAALVM_HOME/bin/gu install native-image
让我们为当前平台生成本机版本(在本例中,将为 macOS 生成本机可执行文件)。
mvn package -Pnative
如果一切正常,我们可以在 ./target 文件夹中找到一个名为的文件。这是应用程序的可执行二进制文件,您可以运行以下命令启动它:.无需使用 JVM(普通:java -cp app:lib/*:etc App.jar),它是一个本机可执行二进制文件。quarkus-echo-1.0-SNAPSHOT-runner
./target/quarkus-echo-1.0-SNAPSHOT-runner
让我们为应用程序生成一个原生 Docker 映像。此命令将创建一个本机映像,即具有 Linux 本机可执行应用程序的 Docker 映像。默认情况下,本机可执行文件是基于当前平台(macOS)创建的,因为我们知道这个生成的可执行文件与容器(Linux)的平台不同,我们将指示Maven构建从容器内部生成可执行文件,生成本机docker映像:
mvn package -Pnative -Dquarkus.native.container-build=true
此时,请确保有一个 Docker 容器运行时,一个工作环境。
该文件将是一个 64 位 Linux 可执行文件,因此自然而然地,这个二进制文件不适用于我们的 macOS,它是为我们的 docker 容器映像构建的。所以,向前迈进......让我们来生成 Docker 镜像......
docker build -t ujr/quarkus-echo -f src/main/docker/Dockerfile.native . ## Testing it... docker run -i --name quarkus-echo --rm -p 8081:8081 ujr/quarkus-echo
关于 Docker 镜像大小的旁注:
最终的 docker 镜像是 115MB,但您可以使用无发行版的镜像版本来拥有一个很小的 Docker 镜像。无发行版映像仅包含您的应用程序及其运行时依赖项,其他所有内容(包管理器、shell 或标准 Linux 发行版中常见的普通程序)都将被删除。应用程序的 Distroless 映像大小为 42.3MB。该文件具有生成它的收据。./src/main/docker/Dockerfile.native-distroless
关于Distroless Images:“ 将运行时容器中的内容限制为应用程序所需的内容是 Google 和其他在生产中使用容器多年的科技巨头采用的最佳实践"
Spring Boot 镜像
至此,大概大家都知道如何制作一个普通的Spring Boot Docker镜像了,我们先跳过细节吧?只有一个重要的观察结果,代码是完全相同的。几乎是一样的,因为我们当然使用的是 Spring 框架注解。这是唯一的区别。您可以在提供的源代码中查看每个细节。
mvn install dockerfile:build
## Testing it...docker run --name springboot-echo --rm -p 8082:8082 ujr/springboot-echo
战斗
让我们启动这两个容器,让它们启动并运行几次,并比较启动时间和内存占用。
在这个过程中,每个容器都被创建和销毁了 10 次。后来,分析了他们的启动时间和内存占用。下面显示的数字是基于所有这些测试的平均结果。
启动时间
显然,当与可扩展性和无服务器架构相关时,这方面可能会发挥重要作用。
关于 Serverless 架构,在此模型中,通常由事件触发临时容器来执行任务/功能。在云环境中,价格通常基于执行次数,而不是以前购买的一些计算容量。因此,这里的冷启动可能会影响这种类型的解决方案,因为容器(通常)只会在执行其任务的时间内处于活动状态。
在可伸缩性中,很明显,如果需要突然横向扩展,启动时间将定义容器完全准备就绪(启动并运行)以响应所呈现的加载方案所需的时间。
这种情况有多突然(需要和快速),更糟糕的情况可能是长时间的冷启动。
让我们看看它们在启动时间方面的表现:
好吧,您可能已经注意到,这是在“启动时间”图中插入的又一个经过测试的选项。实际上,它与Quarkus 应用程序完全相同,但使用 JVM Docker 映像(使用Dockerfile.jvm)生成。正如我们所看到的,即使是使用带有 JVM 的 Docker 映像的应用程序,Quarkus 应用程序的启动时间也比 Spring Boot 更快。
毋庸置疑,Quarkus Native 应用程序显然是赢家,它是迄今为止启动速度最快的应用程序。
内存占用
现在,让我们检查一下内存的情况。检查每个容器应用程序在启动时需要消耗多少内存,以启动并运行,并准备好接收请求。
结论
总而言之,这就是我们在 Linux Ubuntu 中查看的结果:
Quarkus 似乎赢得了这两轮战斗(启动时间和内存足迹),以一些明显的优势战胜了他的对手 SpringBoot。
这可能会让我们想知道......也许是时候考虑一些真实的实验、经验和一些 Quarkus 的尝试了。我们应该看看它在真实世界中的表现如何,它如何适应我们的业务场景,以及在什么方面最有用。
但是,我们不要忘记缺点,正如我们在上面看到的,JVM的某些功能在本机可执行二进制文件中无法(还/容易)工作。无论如何,也许是时候给 Quarkus 一个证明自己的机会了,特别是如果冷启动的问题一直困扰着你。在环境中使用一两个由 Quarkus 驱动的 Pod (K8s) 怎么样,看看一段时间后它的表现会很有意思,不是吗?
相关文章:

微服务架构之争:Quarkus VS Spring Boot
在容器时代(“Docker时代”),无论如何,Java仍然活着。Java在性能方面一直很有名,主要是因为代码和真实机器之间的抽象层,多平台的成本(一次编写,随处运行——还记得吗?&a…...

如何使用ArcGIS Pro拼接影像
为了方便数据的存储和传输,我们在网上获取到的影像一般都是分块的,正式使用之前需要对这些影像进行拼接,这里为大家介绍一下ArcGIS Pro中拼接影像的方法,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的…...

[论文笔记] chatgpt系列 SparseMOE—GPT4的MOE结构
SparseMOE: 稀疏激活的MOE Swtich MOE,所有token要在K个专家网络中,选择一个专家网络。 显存增加。 Experts Choice:路由MOE: 由专家选择token。这样不同的专家都选择到某个token,也可以不选择该token。 由于FFN层的时间复杂度和attention层不同,FFN层的时…...

C# WPF上位机开发(键盘绘图控制)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 在软件开发中,如果存在canvas图像的话,一般有几种控制方法。一种是鼠标控制;一种是键盘控制;还有一…...

《地理信息系统原理》笔记/期末复习资料(10. 空间数据挖掘与空间决策支持系统)
目录 10. 空间数据挖掘与空间决策支持系统 10.1. 空间数据挖掘 10.1.1. 空间数据挖掘的概念 10.1.2. 空间数据挖掘的方法与过程 10.1.3. 空间数据挖掘的应用 10.2. 空间决策支持系统 10.2.1. 空间决策支持系统的概念 10.2.2. 空间决策支持系统的结构 10.2.3. 空间决策…...

uniapp播放 m3u8格式视频 兼容pc和移动端
支持全自动播放、设置参数 自己摸索出来的,花了一天时间,给点订阅支持下,订阅后,不懂的地方可以私聊我。 代码实现 代码实现 1.安装dplayer组件 npm i dplayer2. static/index.html下引入 hls 引入hls.min.js 可以存放在static项目hls下面<script src="/static…...

产品经理之Axure的元件库使用详细案例
⭐⭐ 产品经理专栏:产品专栏 ⭐⭐ 个人主页:个人主页 目录 前言 一.Axure的元件库的使用 1.1 元件介绍 1.2 基本元件的使用 1.2.1 矩形、按钮、标题的使用 1.2.2 图片及热区的使用 1.3 表单元件及表格元件的使用 1.3.1表单元件的使用 1.3.…...

数字化转型对企业有什么好处?
引言 数字化转型已经成为当今商业领域中的一股强大力量,它不仅仅是简单的技术更新,更是企业发展的重要战略转变。随着科技的迅猛发展和全球化竞争的加剧,企业们正在积极探索如何将数字化的力量融入到他们的运营和战略中。 数字化转型不仅是传…...
微信小程序:按钮禁用,避免按钮重复提交
wxml <view class"modal-buttons"><view class"one_btn" bindtap"submit">确认</view><view class"two_btn" bindtap"cancel">取消</view> </view> wxss /* 按钮 */ .modal-buttons…...

JAVA 异常分类及处理
JAVA 异常分类及处理 概念 如果某个方法不能按照正常的途径完成任务,就可以通过另一种路径退出方法。在这种情况下会抛出一个封装了错误信息的对象。此时,这个方法会立刻退出同时不返回任何值。另外,调用这个方法的其他代码也无法继续执行&…...

C语言--求数组的最大值和最小值【两种方法】
🍗方法一:用for循环遍历数组,找出最大值与最小值 🍗方法二:用qsort排序,让数组成为升序的有序数组,第一个值就是最小值,最后一个是最大值 完整代码: 方法一: …...

ES-组合与聚合
ES组合查询 1 must 满足两个match才会被命中 GET /mergeindex/_search {"query": {"bool": {"must": [{"match": {"name": "liyong"}},{"match_phrase": {"desc": "liyong"}}]}}…...

在 Spring Boot 中发送邮件简单实现
Spring Boot 对于发送邮件这种常用功能也提供了开箱即用的 Starter:spring-boot-starter-mail。 通过这个 starter,只需要简单的几行配置就可以在 Spring Boot 中实现邮件发送,可用于发送验证码、账户激活等等业务场景。 本文将通过实际的案…...

深入理解网络 I/O:单 Selector 多线程|单线程模型
🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代 🌲文章所在专栏&…...
Kafka Avro序列化之三:使用Schema Register实现
为什么需要Schema Register 注册表 无论是使用传统的Avro API自定义序列化类和反序列化类 还是 使用Twitter的Bijection类库实现Avro的序列化与反序列化,这两种方法都有一个缺点:在每条Kafka记录里都嵌入了schema,这会让记录的大小成倍地增加。但是不管怎样,在读取记录时…...

EasyExcel
概述 GitHub - alibaba/easyexcel: 快速、简洁、解决大文件内存溢出的java处理Excel工具 EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的…...
java 探针两种模式实战
分为两种 程序运行前的agent:premain 程序运行中的agent:agentmain 在程序运行前的agent javaagent是java命令的一个参数,所以需要通过-javaagent 来指定一个jar包(就是我们要做的代理包)能够实现在主程序运行前来执行…...

uniGUI之MASK遮罩
在页面进行后台数据库操作的时候,不想 用户再进行 页面上的 其他操作,这时候就要 将页面 遮罩。例如UniDBGrid有LoadMask属性。 1]使用ScreenMask函数 2]JS调用 3]一个控件控制遮罩另一个控件(如Button遮罩UniDBGrid) //很简单,本例子就是告…...

DevOps云原生创建devops流水线(微服务项目上传git,打包镜像,部署k8s)
开发和运维人员的解决方案 一、中间件的部署(Sentinel/MongoDB/MySQL) 二、创建DevOps工程 邀请成员 三、创建流水线 四、编辑流水线 ①、拉取代码(若失败,则将制定容器改为maven) 若失败,则将命令改…...
【vim 学习系列文章 13.1 -- 自动命令autocmd 根据文件类型设置vim参数】
文章目录 autocmd 根据文件类型配置vim参数vim 文本类型 autocmd 根据文件类型配置vim参数 在 Vim 中,你可以使用 autocmd (自动命令)来根据文件类型自动执行特定的函数。首先,你需要定义这些函数,然后使用 autocmd 与…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

PH热榜 | 2025-06-08
1. Thiings 标语:一套超过1900个免费AI生成的3D图标集合 介绍:Thiings是一个不断扩展的免费AI生成3D图标库,目前已有超过1900个图标。你可以按照主题浏览,生成自己的图标,或者下载整个图标集。所有图标都可以在个人或…...
深度解析云存储:概念、架构与应用实践
在数据爆炸式增长的时代,传统本地存储因容量限制、管理复杂等问题,已难以满足企业和个人的需求。云存储凭借灵活扩展、便捷访问等特性,成为数据存储领域的主流解决方案。从个人照片备份到企业核心数据管理,云存储正重塑数据存储与…...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...