淘先锋技术网

首页 1 2 3 4 5 6 7

原标题:微服务之争,Quarkus还是Spring Boot

在容器时代(Docker时代),Java仍然保持着活力,但是这一切都在悄悄的改变中,那么下一场技术变革中,谁会一马当先,是Spring Boot还是 Quarkus?

下面让我们在两个用JAVA生成微服务的两个技术架构进行一个对比

1.非常出名的SpringBoot

2.不太出名的Quarkus

介绍:

什么是Quarkus?

一套适用于GraalVM和HotSpot来编写Java应用程序的开源技术。它提供(承诺)超快速的启动时间和更低的内存占用。这使其非常适合容器和无服务器工作负载。它使用Eclipse Microprofile(JAX-RS,CDI,JSON-P)(Java EE的子集)来构建微服务。

GraalVM是通用的多语言虚拟机(Java,Python,Ruby,R,Java,Scala和Kotlin)。GraalVM (特别是Substrate VM)使提前(AOT)编译成为可能,将字节码转换为本地机器代码,从而产生可以本地执行的二进制文件。

请记住,并非所有功能都可以在本机执行中使用,因此AOT编译有其局限性。请注意这句话(来自GraalVM团队):

我们进行的主动静态分析需要一个特定的封闭世界,这意味着在构建时必须知道运行时可访问的所有类和所有字节码。

因此,例如,反射和Java本机接口(JNI)将不起作用,至少需要是开箱即用(这要一些额外的工作)。我们可以在本机映像Java限制文档中找到限制列表。

什么是SpringBoot?

这里只用一句话概括

Spring Boot是建立在Spring框架之上的开源框架,它提供了一种更简单的方法来构建,配置和运行基于Java Web的应用程序。使之成为微服务的理想选择。

开始比较之前,我们需要做一些准备-创建Docker镜像

Quarkus镜像

让我们先创建一个Quarkus程序,稍后我们会把它写入Docker镜像中,基本上,按照Quarkus官方教程做就OK了。

1

mvn io.quarkus:quarkus-maven-plugin:1.0.0.CR2:create \

2

-DprojectGroupId=ujr.combat.quarkus \

3

-DprojectArtifactId=quarkus-echo \

4

-DclassName="ujr.combat.quarkus.EchoResource" \

5

-Dpath="/echo"

在创建了文件目录后,我们创建了两个Dockerfile(src/main/docker):一个用于普通的JVM应用程序镜像,另一个用于本机应用程序镜像。

在生成代码的过程中,我们仅仅需要做的就是添加下面的MAVEN依赖,让我们可以添加JSON内容依赖。

Dockerfile

io.quarkusquarkus-resteasy-jsonb 4

Quarkus在RESTEasy项目实现中使用JAX-RS规范,我们使用下一个命令,就可以运行我们的程序:

mvn clean compile quarkus:dev

在这种模式中,我还是还可以启动热部署,使用下面的命令

Dockerfile

1curl -sw "\n\n" http://localhost:8080/echo/ualter | jq .

下面我们创建Docker镜像

这里下载最新的GraalVM:https://github.com/GraalVM/GraalVM-ce-builds/releases

重要!不要下载最新版本19.3.0,它与Quarkus 1.0不兼容,也许Quarkus 1.1会兼容。现在应该可以工作的版本是GraalVM 19.2.1,下面。

配置其环境变量home path:

Dockerfile

1## At macOS will be: export 2GRAALVM_HOME=/Users/ualter/Developer/quarkus/graalvm-ce-java8-19.2.1/Contents/Home/

然后会在我们的环境中安装Native的GraalVM虚拟镜像

Dockerfile

$GRAALVM_HOME/bin/gu install native-image

下面为当前平台生成native版本(在本例中,将为macOS生成本机可执行文件)。

Dockerfile

mvn package -Pnative

如果一切正常,我们可以在./target文件夹中找到名为quarkus-echo-1.0-SNAPSHOT-runner的文件。这是应用程序的可执行二进制文件,您可以运行以下命令启动它:./target/quarkus-echo-1.0-SNAPSHOT-runner。不需要使用JVM(普通的:java-cp app:lib/*:etc app.jar),它是一个本机可执行二进制文件。

让我们为我们的应用程序生成一个本地Docker映像。此命令将创建本机映像,即带有Linux本机可执行应用程序的Docker映像。默认情况下,本机可执行文件是基于当前平台(macOS)创建的,因为我们知道这个可执行文件与容器(Linux)的平台不同,我们将指示Maven build从容器内部生成可执行文件,生成本机docker映像:

Dockerfile

mvn package -Pnative -Dquarkus.native.container-build=true

这时候,我们已经有了一个Docker容器在运行,一个程序执行的环境。

这个文件将是一个64位的Linux可执行文件,所以很自然,这个二进制文件不会在我们的macOS上运行,它是为我们的docker容器映像构建的,下面我们来使用这个文件

Dockerfile

1docker build -t ujr/quarkus-echo -f src/main/docker/Dockerfile.native . 2 ## Testing it... 3 docker run -i --name quarkus-echo --rm -p 8081:8081 ujr/quarkus-echo

额外说明:

最终的docker镜像是115MB,但是可以使用无发行版的镜像版本创建一个小的docker镜像。无发行版镜像只包含应用程序及其运行时依赖项,其他所有内容(包管理器、shell或标准Linux发行版中常见的普通程序)都将被删除。我们应用程序的不可分发镜像大小为42.3MB。文件./src/main/docker/docker file.native-distroless具有生成该文件的收据。

关于不受欢迎的镜像:“将运行时容器中的内容限制为应用程序所需的内容是谷歌和其他技术巨头多年来在生产中使用容器的最佳实践。”

Spring Boot镜像

怎么生成这个镜像,这里就不多说了,大家自己去Spring.IO上面去看下。

Dockerfile

1mvn install dockerfile:build 2## Testing it... 3 docker run --name springboot-echo --rm -p 8082:8082 ujr/springboot-echo

下面是比较

让我们启动两个容器,启动它们并运行几次,然后比较启动时间和内存占用。

在这个过程中,每个容器都被创建和销毁了10次。随后,分析了它们的启动时间和内存占用。下面显示的数字是基于所有这些测试的平均结果。

启动时间

当涉及到可伸缩性和无服务器体系结构时,启动时间可能会发挥重要作用。

关于无服务器架构,在这个模型中,通常事件会触发一个临时容器来执行任务/功能。在云环境中,价格通常基于执行的次数,而不是以前购买的一些计算容量。因此,这里冷启动可能会影响这类解决方案,因为容器(通常)只有在执行其任务时才是活动的。

在可伸缩性方面,很明显,如果需要突然向外扩展,那么启动时间将定义容器完全准备好(启动并运行)响应所呈现的加载场景所需的时间。

这是多么突然的情况(需要和快速),更糟糕的情况可能是长期冷启动。

让我们看看他们在启动时间方面的表现:

我们在这里,在程序启动的时间就已经开始了下一个测试的启动,实际上,它是同一个Quarkus程序由一个JVM Docker镜像生成,

即使是使用Docker映像和JVM的应用程序,Quarkus应用程序的启动时间也比Spring Boot快。

显然Quarkus是胜利者,Quarkus本机应用程序迄今为止启动最快的。

内存占用

现在,让我们检查一下内存的情况。检查每个容器应用程序在启动时需要消耗多少内存,以便启动和运行,准备接收请求。

结论:

总结一下,这就是我们在Linux Ubuntu中看到的结果:

Quarkus似乎赢得了这两轮比赛(启动时间和内存占用),以明显的优势战胜了对手SpringBoot。

但是我们可以看到的是Quarkus在技术生态和架构生态上还是不够完善的,但是i如果冷启动等问题困扰你,或许可以尝试一下Quarkus。

如果喜欢我的文章,麻烦点个关注呗。返回搜狐,查看更多

责任编辑: