选项卡切换从左到右切换样式_您应该切换到Quarkus吗?

选项卡切换从左到右切换样式

I once had a manager who said “Ask the second question”. When I would ask one of my daughters “Is your homework done?”, I would invariably get a “Yes”. Then I would ask the second question “So it’s ready to be turned in as is?”, and the usual response was something like “Well, I have one more thing to finish”. One question is never enough, the first answer is usually what the person being questioned wants you, or themselves, to believe.

我曾经有一位经理说“问第二个问题”。 当我问我的一个女儿“您的作业完成了吗?”时,我总是会得到一个“是”。 然后,我问第二个问题:“是否准备好按原样上交?”,通常的回答是:“嗯,我还有一件事情要做。” 一个问题永远是不够的,第一个答案通常是被问询的人希望您或他们自己相信什么。

I was recently talking to a Red Hat architect about microservices and OpenShift, and during that conversation Quarkus came up. Having done a lot of Java development in the past, I was pretty interested in this idea of Quarkus. It is a “Kubernetes Native Java stack tailored for OpenJDK HotSpot and GraalVM” that promises significantly quicker startup times and a smaller footprint for Java-based microservices. How can I possibly pass that up? I searched and found a couple articles showing how much faster Quarkus applications start than standard JVM based applications. I decided to try for myself and sure enough my application did start quicker with a smaller footprint. Then following the advice of my former manager I asked the second question: does it run faster? And the answer to that, as it turns out, is “it depends”.

我最近正在与Red Hat架构师谈论微服务和OpenShift,在那次对话中,出现了Quarkus 。 过去做过很多Java开发,我对Quarkus的想法很感兴趣。 它是“专为OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈”,它可以大大缩短启动时间,并减少基于Java的微服务的占用空间。 我怎样才能通过? 我搜索并找到了几篇文章,这些文章显示了Quarkus应用程序的启动速度比标准的基于JVM的应用程序快多少。 我决定自己尝试一下,并确保我的应用程序确实以较小的占用空间启动了更快。 然后,根据前任经理的建议,我问了第二个问题:运行速度是否更快? 事实证明,答案是“取决于”。

建立 (Setup)

In order to get a true test of Quarkus’s potential, I didn’t want to custom build an application with the goal of running Quarkus — that could skew the results by building to purpose. Most of my customers have legacy applications, therefore, converting an existing application is a more realistic use case. I happen to have a small set of microservices, which I’ve used on several other articles, one of which is a Spring Boot application. This microservice, capitol-info, provides CRUD capabilities via REST operations. The first operation returns country capitols via an HTTP GET call. The second operation supports inserting/updating capitols via an HTTP POST.

为了真实地测试Quarkus的潜力,我不想定制运行Quarkus为目标的应用程序,因为它可能会因特定目的而歪曲结果。 我的大多数客户都有旧版应用程序,因此,转换现有应用程序是一个更实际的用例。 我碰巧有一套微服务,我已经在其他几篇文章中使用过,其中之一是Spring Boot应用程序。 这项微服务capitol-info通过REST操作提供CRUD功能。 第一项操作通过HTTP GET调用返回国家国会大厦。 第二个操作支持通过HTTP POST插入/更新国会大厦。

Postman sending HTTP GET and POST calls to Spring Boot, Quarkus, and Quarkus native.
Performance Test Cases
性能测试案例

Red Hat has a good article on how to convert Spring Boot applications to Quarkus. The article covers removing Spring Boot code and build artifacts, and replacing them with Quarkus equivalents. I followed the instructions in the article without too much difficulty. I would say it took less than a half hour to make the changes and get a clean build. Granted, I only had two REST operations, but still the process was fairly smooth.

Red Hat有一篇很好的文章 ,介绍了如何将Spring Boot应用程序转换为Quarkus。 本文介绍了删除Spring Boot代码和构建构件,并用Quarkus等效物替换它们。 我按照本文中的说明进行操作,没有太多困难。 我会说,不到半小时就进行了更改并获得了完整的版本。 当然,我只有两个REST操作,但是过程仍然相当顺利。

本地夸克 (Native Quarkus)

The next step was to build the Quarkus native version, by following the directions, including installing a C compiler. I didn’t have any problem building the native version of the application. However, when I went to run it, there were runtime errors where the microservice couldn’t find a library. Specifically, it was trying to find my JSON database library. I researched the problem and determined that I should use Quarkus extensions, if possible, for the project dependencies. Because the JSON database library had annotations, using an extension was a hard requirement. Unfortunately, the JSON database library that I was using does not have a Quarkus extension. I was left with the choice of building an extension or replacing the code. I decided on replacement.

下一步是按照指示进行操作 ,以构建Quarkus本机版本,包括安装C编译器。 构建应用程序的本机版本没有任何问题。 但是,当我去运行它时,在微服务找不到库的地方存在运行时错误。 具体来说,它试图找到我的JSON数据库库 。 我研究了这个问题,并确定应该对项目依赖项使用Quarkus扩展。 由于JSON数据库库具有批注,因此使用扩展名是一个硬要求。 不幸的是,我使用的JSON数据库库没有Quarkus扩展名。 我可以选择构建扩展或替换代码。 我决定更换。

To simulate similar functionality to the JSON database, I replaced the relevant code with a HashMap and JSON serialization. For serialization I used the GSON library, which I was already using elsewhere in the application. This library does not have a Quarkus extension (as a side note there is an Apache Camel GSON extension, but this microservice isn’t using Camel), but was compilable, because it did not use annotations. Not having an extension turned out to be important, as we will see later.

为了模拟与JSON数据库相似的功能,我用HashMap和JSON序列化替换了相关代码。 对于序列化,我使用了GSON库,该库已经在应用程序的其他地方使用了。 该库没有Quarkus扩展(作为旁注,有一个Apache Camel GSON扩展,但是此微服务未使用Camel),但是可以编译,因为它不使用注释。 事实证明,没有扩展名很重要,我们将在后面看到。

To ensure disk I/O was in the equation and not just pure CPU, I added JSON serialization with GSON, in the form of writing out the HashMap as JSON to the file system. I believe this makes for a more realistic test that would cover more use cases. Basically, the test consists of looking up a capital from a HashMap for the GET operation. In the case of the POST operation, it does a couple of functions in a loop, along with writing JSON to a file, to simulate a load.

为了确保磁盘I / O处于方程式中,而不仅仅是纯粹的CPU中,我以GSON形式添加了JSON序列化,形式是将HashMap作为JSON写出到文件系统中。 我相信这将使测试更加实际,从而涵盖更多的用例。 基本上,测试包括从HashMap查找用于GET操作的资本。 对于POST操作,它会在循环中执行几个功能,并将JSON写入文件中以模拟负载。

For each test, I did three runs of a 1000 batched calls from Postman to the capitol-info microservice. Each batched call did one HTTP GET call and one HTTP POST call with a 10 millisecond delay between the batches. The results of each set of three runs (6000 total HTTP calls) were averaged to help minimize the impacts of outliers and external factors. The tests were run on a MacBook Pro, with an 2.4 GHz 8-Core Intel Core i9, and 32 GB of memory. Both the Spring Boot and Quarkus version ran using GraalVM.

对于每个测试,我从Postman到Capitol-info微服务进行了1000次批量呼叫的三个运行。 每个批处理调用执行一个HTTP GET调用和一个HTTP POST调用,在批处理之间延迟10毫秒。 将每组三个运行(总共6000次HTTP调用)的结果取平均值,以帮助最大程度地减少离群值和外部因素的影响。 这些测试是在配备2.4 GHz 8核Intel Core i9和32 GB内存的MacBook Pro上运行的。 Spring Boot和Quarkus版本都使用GraalVM运行。

结果 (Results)

While faster start times are great, what I’m really looking for is performance improvement at runtime. As will be seen below, Quarkus has yielded some unexpected and perhaps controversial runtime performance results. First, let’s take a quick look at the startup times. As you can see below, Quarkus starts much quicker than Spring Boot and the Quarkus native version is several orders of magnitude faster than both, starting in millisecond time. These startup times are indicative of what I saw running tests, and in line with findings from others using Quarkus.

虽然更快的启动时间很棒,但我真正想要的是在运行时提高性能。 如下所示,Quarkus产生了一些意想不到的甚至是有争议的运行时性能结果。 首先,让我们快速查看启动时间。 如下所示,Quarkus的启动速度比Spring Boot快得多,而Quarkus的本机版本的启动速度要比两者都快几个数量级(从毫秒开始)。 这些启动时间表示我看到的正在运行测试,并且与使用Quarkus的其他人的发现一致。

Spring Boot startup output showing load time of about 3 seconds.
Spring Boot on GraalVM startup time around 2.8 seconds
GraalVM上的Spring Boot启动时间约为2.8秒
Quarkus JVM startup output showing load time of about 3 seconds.
Quarkus on GraalVM startup time around .57 seconds
Quarkus在GraalVM上的启动时间约为.57秒
Quarkus native compile app startup output showing load time of about 3 seconds.
Quarkus native executable startup time around 0.2 seconds
Quarkus本机可执行文件启动时间约为0.2秒

So far so good. Note how in the Quarkus screenshots, you can see the installed features, or extensions: cdi; resteasy; and resteasy-jsonb. Now, let’s take a look at the results of the runtime test from the standpoint of how long it takes for the test to run:

到目前为止,一切都很好。 注意在Quarkus屏幕截图中如何看到已安装的功能或扩展:cdi; 高枕无忧; 和resteasy-jsonb。 现在,从运行测试需要多长时间的角度来看一下运行时测试的结果:

Chart showing REST GET and POST operation call times running on MacOS.
REST operation test results on MacOS
MacOS上的REST操作测试结果

Wait, what? The GET response time graph looks good, with the native executable application handily beating the GraalVM versions. But how can it be that POST calls against the native version takes three times as long, at 134 ms, to run than either the Spring Boot (43 ms) or the Quarkus in GraalVM (42 ms)? The major difference between the GET and POST operations was the introduction of file I/O, so my first thought was maybe it had something to do with the MacOS disk I/O library. I decided to port the code over to an old laptop running Ubuntu, and run the same battery of tests. The laptop is a 3rd generation i7, 8GB memory, SSD. Here are the average test times:

等一下 GET响应时间图看起来不错,本机可执行应用程序轻松击败了GraalVM版本。 但是,对本机版本进行POST调用所花费的时间(134毫秒)比Spring Boot(43毫秒)或GraalVM中的Quarkus(42毫秒)要长三倍? GETPOST操作之间的主要区别是文件I / O的引入,因此我首先想到的可能与MacOS磁盘I / O库有关。 我决定将代码移植到运行Ubuntu的旧笔记本电脑上,并进行相同的测试。 笔记本电脑是第三代i7、8GB内存,SSD。 这是平均测试时间:

Chart showing REST GET and POST operation call times running on Ubuntu.
REST operation test results on Ubuntu
Ubuntu上的REST操作测试结果

The result is the same, native POST calls with the file I/O are just as slow on the Linux machine. The MacOS and Ubuntu test times are also shown in the table below for easy reference.

结果是一样的,在Linux机器上使用文件I / O进行本机POST调用的速度一样慢。 下表还显示了MacOS和Ubuntu的测试时间,以方便参考。

Image for post
Performance test results — times in milliseconds
性能测试结果-时间(以毫秒为单位)

货柜化 (Containerization)

The next step was comparing the Spring Boot version to the Quarkus native executable version while running in a Docker container and Kubernetes. I built the Docker images, using the ubi8 minimal base Docker image for Quarkus and the OpenJDK 11.0.7-jre-slim base image for the Spring Boot container. The tests were then run against Docker and Kubernetes.

下一步是在Docker容器和Kubernetes中运行时将Spring Boot版本与Quarkus本机可执行版本进行比较。 我使用Quar8的ubi8最小基础Docker映像和Spring Boot容器的OpenJDK 11.0.7-jre-slim基础映像构建了Docker映像。 然后针对Docker和Kubernetes运行测试。

Tests diagram calling Docker and Kubernetes.
Test cases using Docker and Kubernetes
使用Docker和Kubernetes的测试用例

The startup times between Spring Boot and Quarkus Native still show an amazing performance improvement from switching Spring Boot to Quarkus. Below is the log output for the Spring Boot container, which takes around 4 seconds to start.

从Spring Boot切换到Quarkus,Spring Boot和Quarkus Native之间的启动时间仍然显示出惊人的性能改进。 下面是Spring Boot容器的日志输出,启动大约需要4秒钟。

Docker Quarkus startup time of 4.3 seconds

The Docker container running the Quarkus native executable application, took 0.012s to start, as shown below. That is an amazing improvement in start time.

运行Quarkus本机可执行应用程序的Docker容器以0.012s的时间启动,如下所示。 这是启动时间的惊人改进。

Docker Quarkus startup time of 0.012 seconds

Unfortunately, the runtime results still show the Quarkus native code POST call times are slower than the equivalent JVM, while the native GET remains faster than the JVM GET.

不幸的是,运行时结果仍然显示Quarkus本机代码POST调用时间比等效的JVM慢,而本机GET仍然比JVM GET快。

Docker and Kubernetes test performance graphs
REST operation test results running in a container
在容器中运行的REST操作测试结果

The odd thing is that the POST operation is slightly faster running in Docker than directly on the OS.

奇怪的是,在Docker中运行POST操作的速度比在OS上运行的速度要快一些。

调查中 (Investigation)

At this point, it is clear that POST operation in the Quarkus native executable version is much slower than the JVM version. It is slower regardless of whether it is running with Spring Boot or Quarkus, or directly on the OS versus a container. Because the main difference between the GET and POST was the serialization and disk I/O, I focused my investigations on that area. Knowing that it was not using a Quarkus GSON extension, I swapped that out for JSON-B based code. JSON-B has a Quarkus extension, so I expected to see a performance improvement in the native version over the JVM version. Below is the code that uses GSON for serializing Java objects to JSON and writing to disk.

至此,很明显,Quarkus本机可执行版本中的POST操作比JVM版本慢得多。 无论它是与Spring Boot还是Quarkus一起运行,还是直接在OS与容器上运行,它都比较慢。 因为GETPOST之间的主要区别是序列化和磁盘I / O,所以我将研究重点放在了这一领域。 知道它没有使用Quarkus GSON扩展,所以我将其替换为基于JSON-B的代码。 JSON-B具有Quarkus扩展,因此我希望本机版本的性能优于JVM版本。 以下是使用GSON将Java对象序列化为JSON并写入磁盘的代码。

GSON Java object serialization
GSON Java对象序列化

This code was converted to use JSON-B, which has a Quarkus extension.

此代码已转换为使用JSON-B(具有Quarkus扩展名)。

JSON-B Java object serialization
JSON-B Java对象序列化

Once the code was converted, I tested again. The chart below shows the HTTP POST operation average time for Spring Boot and Quarkus native.

代码转换后,我再次测试。 下表显示了Spring Boot和Quarkus本机的HTTP POST操作平均时间。

REST POST operation graph shown native faster than Spring Boot.
REST POST operation test results, using JSON-B on MacOS
REST POST操作测试结果,在MacOS上使用JSON-B

The table below shows the results of both the GET and POST calls:

下表显示了GET和POST调用的结果:

Table with JSON-B runtimes.
REST POST operation test times, using JSON-B on MacOS
REST POST操作测试时间,在MacOS上使用JSON-B

As expected, the native compiled code now beats the JVM code, however the JSON-B code is still slower than the GSON version.

正如预期的那样,本机编译代码现在胜过了JVM代码,但是JSON-B代码仍然比GSON版本

结论 (Conclusion)

My work converting Spring Boot to Quarkus and then running the subsequent tests, left me with more questions than answers. It also gave me some insights. First, Quarkus code is cleaner and less verbose than Spring Boot for developing REST services. Second, in a situation were one is doing a lot of autoscaling and start time is crucial, again, Quarkus wins hands down. Third, it seems evident that without the proper extensions, Quarkus could introduce latencies that are so significant they would stop the adoption of the native executable version of Quarkus. At this point, I would probably choose to develop a new REST application with Quarkus if I could get or create the needed extensions.

我的工作将Spring Boot转换为Quarkus,然后运行后续测试,这给我带来的问题多于答案。 这也给了我一些见识。 首先,用于开发REST服务的Quarkus代码比Spring Boot更加简洁明了。 其次,在一种情况下,人们正在做大量的自动缩放,而启动时间至关重要,同样,Quarkus胜出。 第三,似乎很明显,如果没有适当的扩展,Quarkus可能会引入如此巨大的等待时间,以至于无法采用Quarkus的本机可执行版本。 在这一点上,如果我能够获得或创建所需的扩展,我可能会选择使用Quarkus开发一个新的REST应用程序。

There are a couple of other observations from these tests the bear calling out:

从熊熊的呼唤中可以看出,从这些测试中可以得出其他一些结论:

  1. The choice of Java libraries can have significant impacts on performance. It’s been my experience from most projects I’ve worked on, developers tended to grab well known libraries and just use them without independently measuring their performance. Performance concerns generally focus on more coarse granular areas, such as network protocols, data verbosity, messaging engines, etc. There are an enormous number of Java libraries, and it would be nearly impossible for a team to performance test them all. I have not found this information forthcoming either, which seems to be in of itself a problem.

    Java库的选择可能会对性能产生重大影响。 这是我从从事过的大多数项目中获得的经验,开发人员倾向于获取众所周知的库,并且仅在不独立衡量其性能的情况下使用它们。 性能关注点通常集中在更粗糙的区域,例如网络协议,数据冗长程度,消息传递引擎等。有大量的Java库,因此团队几乎不可能对它们全部进行性能测试。 我也没有发现即将到来的信息,这似乎本身就是一个问题。
  2. I have to say I was quite shocked that the performance of my new MacBook Pro, running an i9 processor, was not a whole lot better than a seven year old Ubuntu laptop with 1/4 of the memory. I’m not sure if this is a measure of Java, thermal throttling, the fact that both use SSDs and that was a limiting factor, or some other reasons, but I think it bears further investigation and more tests against a variety hardware.

    我不得不说,令我震惊的是运行i9处理器的新款MacBook Pro的性能并没有比拥有1/4内存的7年老Ubuntu笔记本电脑好很多。 我不确定这是否是Java的衡量标准,是否进行热节流,是否都使用SSD以及是否存在限制因素或其他一些原因,但是我认为它需要针对各种硬件进行进一步的研究和更多的测试。

翻译自: https://itnext.io/should-you-switch-to-quarkus-4b89eedfe5fe

选项卡切换从左到右切换样式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值