微服务架构之争:Quarkus VS Spring Boot

2023-12-16 12:45

本文主要是介绍微服务架构之争:Quarkus VS Spring Boot,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在容器时代(“Docker时代”),无论如何,Java仍然活着。Java在性能方面一直很有名,主要是因为代码和真实机器之间的抽象层,多平台的成本(一次编写,随处运行——还记得吗?),中间有一个JVM(JVM:模拟真实机器的软件机器)。

如今,有了微服务架构,也许它不再有意义,也没有任何优势,为总是在同一地方和平台上运行的东西Docker 容器 — Linux 环境)构建多平台(解释)的东西。可移植性现在不那么重要了(也许比以往任何时候都更重要),那些额外的抽象级别并不重要。

话虽如此,让我们对在 Java 中生成微服务的两种替代方案进行简单而原始的比较:非常著名的 Spring Boot 和不太知名的 Quarkus

对手

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

SpringBoot

不用多介绍了,用一句话说(随意跳过它):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的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/500524

相关文章

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

SpringBoot整合OpenFeign的完整指南

《SpringBoot整合OpenFeign的完整指南》OpenFeign是由Netflix开发的一个声明式Web服务客户端,它使得编写HTTP客户端变得更加简单,本文为大家介绍了SpringBoot... 目录什么是OpenFeign环境准备创建 Spring Boot 项目添加依赖启用 OpenFeig

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot整合mybatisPlus实现批量插入并获取ID详解

《SpringBoot整合mybatisPlus实现批量插入并获取ID详解》这篇文章主要为大家详细介绍了SpringBoot如何整合mybatisPlus实现批量插入并获取ID,文中的示例代码讲解详细... 目录【1】saveBATch(一万条数据总耗时:2478ms)【2】集合方式foreach(一万条数

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖