graalvm_在graalvm上的quarkus中运行微服务

graalvm

This is the fifth part of a series on building a microservice in Quarkus. The other parts were:

Ť他是在Quarkus建设的microService一系列的五分之一。 其他部分是:

In this part we are going to deploy the service running in GraalVM.

在这一部分中,我们将部署在GraalVM中运行的服务。

GraalVM (GraalVM)

GraalVM is a game-changing technology that has only been production ready since 2019. It is a Java VM that contains a JIT compiler and supports building of native images allowing AOT (Ahead Of Time) compilation of java applications. The executable file built by the native image does not run on a JVM but as a platform-specific native application. The binary image contains all of the necessary libraries and dependencies significantly reducing the startup and execution time.

GraalVM是一项改变游戏规则的技术,自2019年以来才投入生产。它是一种Java VM,其中包含JIT编译器并支持构建本机映像,从而允许对Java应用程序进行AOT(提前)编译。 由本机映像构建的可执行文件不在JVM上运行,而是作为特定于平台的本机应用程序运行。 二进制映像包含所有必需的库和依赖项,从而大大减少了启动和执行时间。

安装GraalVM (Installing GraalVM)

You can get instructions for downloading GraalVM for your OS of choice here .

您可以在此处获得有关为所选操作系统下载GraalVM的说明。

Next configure the runtime. Here is how you would do it for macOS

接下来配置运行时。 这是针对macOS的操作方法

export GRAALVM_HOME=/Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.1.0/Contents/Home

For building native images you will need to install the native image tool

要构建本机映像,您将需要安装本机映像工具

$ {GRAALVM_HOME}/bin/gu install native-image

Once you have installed the native image tool you can create native image binaries using the tool

安装本机映像工具后,您可以使用该工具创建本机映像二进制文件

$ native-image my-app.jar

This creates a native binary in the current directory. You can now invoke the binary as follows:

这将在当前目录中创建一个本地二进制文件。 现在,您可以按以下方式调用二进制文件:

$ ./my-app

建立本机映像 (Building the Native Image)

You can follow along with the code by pulling the branch for this article

您可以通过拉动本文的分支来遵循代码

git clone git@github.com:iainporter/sms-service.git
cd sms-service
git checkout part_five

Up until now we have built the SMS microservice to run in a JVM. To run it as a native image we need to either pass an argument to maven on the command line:

到目前为止,我们已经构建了可以在JVM中运行的SMS微服务。 要将其作为本机映像运行,我们需要在命令行中将参数传递给maven:

mvn install -Dquarkus.package.type=native

Or we can add a profile and use the same argument which also allows us to run integration tests against the native image. Before we do that however let’s add a docker file to build a minimal image in which to run the native executable.

或者,我们可以添加一个配置文件并使用相同的参数,这也允许我们针对本机映像运行集成测试。 但是,在执行此操作之前,让我们添加一个docker文件来构建一个最小的映像,以在其中运行本机可执行文件。

FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1
WORKDIR /deployments/
COPY --chown=1001:root target/*-runner /deployments/application
EXPOSE 8080
USER 1001
CMD ./application -Dquarkus.http.host=0.0.0.0

The profile in the pom

pom中的配置文件

<profile>
    <id>native</id>
    <activation>
        <property>
            <name>native</name>
        </property>
    </activation>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                        <configuration>
                            <systemPropertyVariables>
                                <native.image.path>
                                    ${project.build.directory}/${project.build.finalName}-runner
                                </native.image.path>
                            </systemPropertyVariables>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.6.0</version>
                <executions>
                    <!-- Create new docker image -->
                    <execution>
                        <id>docker-build-service</id>
                        <phase>install</phase>
                        <goals>
                            <goal>exec</goal>
                        </goals>
                        <configuration>
                            <executable>docker</executable>
                            <workingDirectory>${project.basedir}</workingDirectory>
                            <arguments>
                                <argument>build</argument>
                                <argument>-f</argument>
                                <!-- build the image with the native executable
                                     use mvn install -Pnative to build-->
                                <argument>Dockerfile.native</argument>
                                <argument>-t</argument>
                                <argument>porterhead/sms-service</argument>
                                <argument>.</argument>
                            </arguments>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <properties>
        <quarkus.package.type>native</quarkus.package.type>
    </properties>
</profile>

Now we can install the executable with the maven command

现在我们可以使用maven命令安装可执行文件

mvn clean install -Pnative

It is here that we run into trouble. In order to build the native executable the GraalVM compiler needs to run a static analysis of the code to perform ahead of time compilation. It has to make a closed world assumption about the code, meaning that all classes have to be available at compile time. No dynamic class loading at runtime or java agents such as JMX, and the use of reflection is limited. All of these limitations are what make the application fast to boot so compromises have to be made. Quarkus is built to run on GraalVM and is optimised for that purpose.

我们在这里遇到了麻烦。 为了构建本机可执行文件,GraalVM编译器需要对代码进行静态分析,以便提前进行编译。 它必须对代码做出封闭的假设,这意味着所有类都必须在编译时可用。 在运行时或JMX之类的Java代理中不会动态加载类,并且反射的使用受到限制。 所有这些限制是使应用程序快速启动的原因,因此必须做出妥协。 Quarkus可以在GraalVM上运行,并且为此目的进行了优化。

The SMS microservice makes use of the OKHttp client that falls over at compilation time:

SMS微服务利用在编译时掉落的OKHttp客户端:

Error: No instances of sun.security.provider.NativePRNG are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use -H:+TraceClassInitialization.
Detailed message:
Trace: object java.security.SecureRandom

There are a bunch of properties that you can use to tweak the compiler behaviour but in this instance it gives us an opportunity to rip out the rest client and use the rest client in Quarkus which won’t have compilation issues.The Rest client interface can be found here and the implementation here. Once we have replaced the rest client the application compiles to a native executable.

您可以使用一堆属性来调整编译器的行为,但是在这种情况下,它为我们提供了机会,可以淘汰REST客户端并在Quarkus中使用REST客户端,而不会出现编译问题。发现这里和实施在这里 。 一旦我们替换了其余客户端,应用程序将编译为本地可执行文件。

内存占用空间和启动时间 (Memory Footprint and Boot Time)

Now that we can build the native application we can compare the memory size and startup time. The normal JVM image size is 559MB

现在我们可以构建本机应用程序,可以比较内存大小和启动时间了。 正常的JVM映像大小为559MB

Image for post
Image size for JVM build
JVM构建的映像大小

The startup time for the JVM image is over 15s

JVM映像的启动时间超过15秒

Image for post
Boot time for JVM image
JVM映像的启动时间

The native image size is less than half of the JVM image

本机映像大小小于JVM映像的一半

Image for post

The startup time is lightening fast. In fact it is so quick that is starts up before the postgres database is ready and so fails to start. To fix this we need to add a wait utility to the container

启动时间Swift缩短。 实际上,它是如此之快,以至于在postgres数据库准备就绪之前就已启动,因此无法启动。 要解决此问题,我们需要在容器中添加一个wait实用程序

ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait
EXPOSE 8080
USER 1001
CMD /wait && ./application -Dquarkus.http.host=0.0.0.0

We make use of this in the docker-compose file

我们在docker-compose文件中使用它

environment:
WAIT_HOSTS: postgres-db:5432

The sms service will wait until postgres is available until starting up. When it does start up the result is less than 2 seconds.

短信服务将等到postgres可用后再启动。 当它启动时,结果不到2秒。

Image for post

This might seem like a long time but consider that the service has to connect to the database, run several flyway migrations, as well as set up the debezium connector to tail the database logs and set up kafka listeners. Compared to the JVM image it is incredibly fast.

这可能看起来很长一段时间,但考虑到该服务必须连接到数据库,运行多个迁移迁移,以及设置debezium连接器以尾随数据库日志并设置kafka侦听器。 与JVM映像相比,它的速度非常快。

The code for this whole series on building a production-ready microservice in Quarkus is available here.

有关在Quarkus中构建生产就绪的微服务的整个系列的代码,请参见此处

翻译自: https://medium.com/@changeant/running-a-microservice-in-quarkus-on-graalvm-52d6b42a5840

graalvm

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值