乐趣区

关于后端:quarkus实战之二应用的创建构建部署

欢送拜访我的 GitHub

这里分类和汇总了欣宸的全副原创 (含配套源码):https://github.com/zq2599/blog_demos

本篇概览

  • 本文是《quarkus 实战》系列的第二篇,指标是开发 HelloWorld 利用,让咱们对 quarkus 有最根本的理解,写好的代码会在以下几种场景运行,这应该笼罩了大部分运行状况,绿色背景的示意具体的运行形式,可见一共有五种:
  • 为达到上述指标,接下来的文章会被划分为这几个局部:
  • 介绍常见三种创立 quarkus 工程的形式
  • 创立 quarkus 工程
  • IDE 导入
  • 大量编码
  • 用 maven 启动 dev 模式,并验证
  • 生成二进制可执行文件,并验证
  • 制作成 docker 镜像,并验证
  • 接下来,一起实战吧

    创立工程的形式

  • 万丈高楼平地起,首先要面对的是如何创立 quarkus 我的项目,与 SpringBoot 相似,quarkus 为咱们提供了多种辅助形式:
  • IDEA 反对创立 quarkus 我的项目:

    备注:我的 mac 和 ubuntu 上的 IDEA 都 <font color=”red”> 没见到这个选项 </font>,难道我装了两个假的 IDEA?

  • maven 命令反对创立,如下:

    mvn io.quarkus.platform:quarkus-maven-plugin:2.7.1.Final:create \
      -DprojectGroupId=org.acme \
      -DprojectArtifactId=getting-started \
      -Dextensions="resteasy"
    cd getting-started
  • 第三种是通过页面操作,在线创立,这种办法直观且简略(不必记命令),举荐应用,关上地址:<font color=”blue”>https://code.quarkus.io/</font>,增加本人的 maven 配置,而后下载网站生成的工程包,如下图:
  • 集体对命令行的形式比拟偏爱,接下来就用命令行创立工程吧

    创立工程

  • 执行以下命令,创立名为 <font color=”blue”>hello-quarkus</font> 的 maven 工程

    mvn "io.quarkus:quarkus-maven-plugin:create" \
    -DprojectGroupId="com.bolingcavalry" \
    -DprojectArtifactId="hello-quarkus" \
    -DprojectVersion="1.0-SNAPSHOT" \
    -DclassName="HobbyResource" \
    -Dpath="actions"
  • 有了阿里云的减速,期待五分钟左右实现我的项目创立,控制台输入如下:

    [INFO] -----------
    [INFO] 
    applying codestarts...
    [INFO] 📚  java
    🔨  maven
    📦  quarkus
    📝  config-properties
    🔧  dockerfiles
    🔧  maven-wrapper
    🚀  resteasy-codestart
    [INFO] 
    -----------
    [SUCCESS] ✅  quarkus project has been successfully generated in:
    --> /home/will/temp/202202/02/24/001/hello-quarkus
    -----------
    [INFO] 
    [INFO] ========================================================================================
    [INFO] Your new application has been created in /home/will/temp/202202/02/24/001/hello-quarkus
    [INFO] Navigate into this directory and launch your application with mvn quarkus:dev
    [INFO] Your application will be accessible on http://localhost:8080
    [INFO] ========================================================================================
    [INFO] 
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  02:10 min
    [INFO] Finished at: 2022-02-24T08:03:03+08:00
    [INFO] ------------------------------------------------------------------------
  • 用 tree 命令看看我的项目构造,是个规范的 maven 工程,只是多了个 docker 目录,外面有几个 Dockerfile 文件,应该是用来制作镜像的吧:

    will@lenovo:~/temp/202202/02/24/001$ tree
    .
    └── hello-quarkus
      ├── mvnw
      ├── mvnw.cmd
      ├── pom.xml
      ├── README.md
      └── src
          ├── main
          │   ├── docker
          │   │   ├── Dockerfile.jvm
          │   │   ├── Dockerfile.legacy-jar
          │   │   ├── Dockerfile.native
          │   │   └── Dockerfile.native-micro
          │   ├── java
          │   │   └── com
          │   │       └── bolingcavalry
          │   │           └── HobbyResource.java
          │   └── resources
          │       ├── application.properties
          │       └── META-INF
          │           └── resources
          │               └── index.html
          └── test
              └── java
                  └── com
                      └── bolingcavalry
                          ├── HobbyResourceTest.java
                          └── NativeHobbyResourceIT.java
  • directories, 13 files

  • 先察看 pom.xml,看有哪些要留神的配置,首先是 dependencyManagement 节点,可见为了保护各依赖库的版本关系,quarkus 应用了 BOM 治理,这样对用户来说就很不便了:

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>${quarkus.platform.group-id}</groupId>
          <artifactId>${quarkus.platform.artifact-id}</artifactId>
          <version>${quarkus.platform.version}</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
  • 而后是 quarkus 的 maven 插件,如下图,可见此插件提供了丰盛的性能,这些不在本篇开展,留待前面应用到了再说吧:

    IDE 导入

  • 此时能够用 IDE 导入这个 maven 工程了,我这边用的是 IDEA,能够看到主动生成的类 HobbyResource.java,是个 web 接口响应类:
  • 如下图红框,做一点小小的改变,用于验证是否失效:
  • 改了 web 接口的返回值,还要记得批改对应的单元测试代码,否则测试就不能通过了,批改 HobbyResourceTest.java,如下图黄框所示,本来是 <font color=”red”>is</font> 办法,当初改为 <font color=”red”>containsString</font>:

启动服务 (dev 模式)

  • dev 模式能够看到更多外部信息,适宜开发阶段应用,执行以下命令即可 dev 模式启动服务:

    mvn compile quarkus:dev
  • 控制台输入以下信息,示意服务已启动(还列出了已反对的 feature),还问你要不要持续做单元测试:

    [INFO] Nothing to compile - all classes are up to date
    Listening for transport dt_socket at address: 5005
    __  ____  __  _____   ___  __ ____  ______ 
     --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
     -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
    --\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
    2022-02-25 08:07:33,050 INFO  [io.quarkus] (Quarkus Main Thread) hello-quarkus 1.0-SNAPSHOT on JVM (powered by Quarkus 2.7.1.Final) started in 1.580s. Listening on: http://localhost:8080
    
    2022-02-25 08:07:33,066 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
    2022-02-25 08:07:33,067 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy, smallrye-context-propagation, vertx]
    
    --
    Tests paused
    Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
  • 我这里输出 <font color=”blue”>r</font> 示意继续执行单元测试,期待测试用例执行实现后,如下图:
  • 用浏览器拜访 <font color=”blue”>http://localhost:8080/actions</font>,即可看到响应信息,如下图,内容与咱们批改的统一:
  • 拜访 <font color=”blue”>http://localhost:8080/q/dev/</font>,能够看到丰盛的零碎信息,该地址只在 dev 模式无效:

生成 jar 包

  • 方才的 mvn 命令能够启动服务,然而仅适宜用在开发环境,正式部署我的项目时,咱们更罕用的形式是做成 jar 文件再用 java 运行,来看如何将我的项目做成 jar
  • 咱们晓得,整个我的项目依赖了其余的 jar 库,因而仅仅将 HobbyResource.java 制作成 jar 是不够的,咱们须要将所有 HobbyResource.java 编译后与其余依赖 jar 合并在一起,做成一个残缺的 jar(SpringBoot 利用也是这么做的),这种 jar,官网称之为 <font color=”blue”>uber-jar</font>
  • 打包,uber-jar(含依赖库),能够用 java11 启动执行,然而不含 http://localhost:8080/q/dev/ 网页性能:
  • 制作 uber-jar 的命令很简略,带上 <font color=”blue”>quarkus.package.type</font> 参数即可,残缺命令如下:

    mvn clean package -U -Dquarkus.package.type=uber-jar
  • 控制台输入如下,可见生成了名为 <font color=”blue”>hello-quarkus-1.0-SNAPSHOT.jar</font> 的 jar 文件:

    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-quarkus ---
    [INFO] Building jar: /home/will/temp/202202/02/24/001/hello-quarkus/target/hello-quarkus-1.0-SNAPSHOT.jar
    [INFO] 
    [INFO] --- quarkus-maven-plugin:2.7.1.Final:build (default) @ hello-quarkus ---
    [INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building uber jar: /home/will/temp/202202/02/24/001/hello-quarkus/target/hello-quarkus-1.0-SNAPSHOT-runner.jar
    [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 2837ms
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  26.274 s
    [INFO] Finished at: 2022-02-26T09:05:51+08:00
    [INFO] ------------------------------------------------------------------------
  • 启动利用,命令是 <font color=”blue”>java -jar hello-quarkus-1.0-SNAPSHOT-runner.jar</font>,如下,0.8 秒还挺快:

    will@lenovo:~/temp/202202/02/24/001/hello-quarkus/target$ java -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
    __  ____  __  _____   ___  __ ____  ______ 
     --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
     -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
    --\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
    2022-02-26 09:12:12,968 INFO  [io.quarkus] (main) hello-quarkus 1.0-SNAPSHOT on JVM (powered by Quarkus 2.7.1.Final) started in 0.841s. Listening on: http://0.0.0.0:8080
    2022-02-26 09:12:12,990 INFO  [io.quarkus] (main) Profile prod activated. 
    2022-02-26 09:12:12,990 INFO  [io.quarkus] (main) Installed features: [cdi, resteasy, smallrye-context-propagation, vertx]
  • 浏览器拜访服务,失常响应:

    制作二进制可执行文件

  • 接下来要体验的是 quarkus 的特色了:将我的项目制作成二进制可执行文件
  • 首先请确认以后环境的 docker 服务失常
  • 其次内存不要太小(在 macbook 上试过,可用内存低于 4G 时报错:Exit code was 137 which indicates an out of memory error)
  • 简略说一下二进制可执行文件是如何制作的:
  • 咱们只须要执行 maven 命令即可,在命令中带些参数,这些参数是给 quarkus 的 maven 插件用的
  • quarkus 的 maven 插件会下载一个 docker 镜像 (ubi-quarkus-native-image)
  • 而后用此镜像创立一个容器
  • 容器中有 GraalVM 环境,用此环境将制作二进制可执行文件
  • 制作胜利后,容器被销毁
  • 下面步骤虽多,咱们的实际操作却很简略,只有第一步,执行如下命令即可:

    mvn clean package -U -DskipTests -Dnative -Dquarkus.native.container-build=true
  • 上述命令有肯定概览产生 Out Of Memory 谬误,如果你电脑的内存短缺,能够酌情指定 JVM 的最大堆内存,残缺命令如下,可见减少了 <font color=”blue”>-Dquarkus.native.native-image-xmx</font> 参数

    mvn clean package -U -DskipTests -Dnative -Dquarkus.native.native-image-xmx=4096m -Dquarkus.native.container-build=true
  • 首次下载 docker 镜像会耗费一点工夫,另外 CPU 会呈现暴涨,如下图:
  • 我这边耗时两分钟实现了二进制文件制作,控制台输入如下:

    [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildStep] Running Quarkus native-image plugin on GraalVM 21.3.1 Java 11 CE (Java Version 11.0.14+9-jvmci-21.3-b09)
    [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] docker run --env LANG=C --rm --user 1000:1000 -v /home/will/temp/202202/02/24/001/hello-quarkus/target/hello-quarkus-1.0-SNAPSHOT-native-image-source-jar:/project:z --name build-native-TArNh quay.io/quarkus/ubi-quarkus-native-image:21.3-java11 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManagerGraalVM -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=zh -J-Duser.country=CN -J-Dfile.encoding=UTF-8 -H:-ParseOnce -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy\$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -J-Djava.awt.headless=true -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http -H:-UseServiceLoaderFeature -H:+StackTrace hello-quarkus-1.0-SNAPSHOT-runner -jar hello-quarkus-1.0-SNAPSHOT-runner.jar
    [hello-quarkus-1.0-SNAPSHOT-runner:24]    classlist:   3,543.22 ms,  1.18 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]        (cap):     615.36 ms,  1.18 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]        setup:   2,545.56 ms,  1.18 GB
    02:04:45,844 INFO  [org.jbo.threads] JBoss Threads version 3.4.2.Final
    [hello-quarkus-1.0-SNAPSHOT-runner:24]     (clinit):     653.12 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]   (typeflow):   5,560.43 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]    (objects):  25,577.19 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]   (features):   1,546.08 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]     analysis:  34,608.07 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]     universe:   1,705.85 ms,  3.30 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]      (parse):   6,557.68 ms,  4.91 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]     (inline):   8,785.79 ms,  5.82 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]    (compile):  33,586.33 ms,  6.02 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]      compile:  51,302.42 ms,  6.02 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]        image:   3,213.24 ms,  6.02 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]        write:     608.88 ms,  6.02 GB
    [hello-quarkus-1.0-SNAPSHOT-runner:24]      [total]:  97,869.00 ms,  6.02 GB
    # Printing build artifacts to: /project/hello-quarkus-1.0-SNAPSHOT-runner.build_artifacts.txt
    [INFO] [io.quarkus.deployment.pkg.steps.NativeImageBuildRunner] docker run --env LANG=C --rm --user 1000:1000 -v /home/will/temp/202202/02/24/001/hello-quarkus/target/hello-quarkus-1.0-SNAPSHOT-native-image-source-jar:/project:z --entrypoint /bin/bash quay.io/quarkus/ubi-quarkus-native-image:21.3-java11 -c objcopy --strip-debug hello-quarkus-1.0-SNAPSHOT-runner
    [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 174203ms
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  02:58 min
    [INFO] Finished at: 2022-02-26T10:06:08+08:00
    [INFO] ------------------------------------------------------------------------
  • 此刻,在工程的 target 目录下,呈现了名为 <font color=”blue”>hello-quarkus-1.0-SNAPSHOT-runner</font> 的二进制可执行文件,这就是本次构建的后果
  • 这个 <font color=”blue”>hello-quarkus-1.0-SNAPSHOT-runner</font> 文件,已不再是通常了解的 <font color=”red”>java 虚拟机 +class 文件 </font> 那样的利用了,这是个基于 GraalVM 构建的二进制文件,它与传统 java 利用的对比方下图所示,它是绿色的那个,可见从速度到内存,都比传统 java 利用有不小的劣势:
  • 执行这个文件,如下图,0.016 秒的启动工夫,优良:
  • 再用零碎监视器查看内存状况,5MB,厉害了:
  • 用浏览器拜访,响应失常:
  • 至此,java 利用制作成二进制可执行文件的操作就实现了,性能的晋升的确很显著,对于这个制作的原理和细节不在本文开展,您有趣味的话能够关注 GravvlVM 的材料

制作镜像(基于二进制文件)

  • 有时咱们须要将服务部署在 docker 或 k8s 环境,所以,接下来尝试将这个 java 工程制作成 docker 镜像
  • 先来回顾一下,将 java 工程制作成 docker 镜像,如果您之前有过这方面的经验,应该记得上面相熟的步骤:
  • 筹备一个集成了 java 环境的镜像作为根底镜像
  • 编译 java 工程,失去 jar、class、资源文件等
  • 将 jar、class、资源文件这些复制到根底镜像中
  • 下面就是将 java 工程制作成 docker 镜像的个别步骤,那么,在 quarkus 我的项目中,还须要依照上述步骤去制作 docker 镜像吗?
  • <font color=”red”> 当然不须要啦!</font>
  • 只有找个 linux 零碎做为根底镜像,把方才做好的二进制可执行文件复制进去不就能够了吗?
  • 贴心的 quarkus,把 Dockerfile 都为咱们筹备好了,就是下图左侧红框中那个,右侧是其内容,就那么寥寥几行,外围是复制那个二进制文件:
  • 执行上面的命令,轻松实现镜像制作:

    docker build \
    -f src/main/docker/Dockerfile.native \
    -t bolingcavalry/hello-quarkus:0.0.1 .
  • 镜像制作实现后,如下图,镜像只有 144M 大小,优良:
  • 执行以下命令运行镜像试试:

    docker run -i --rm -p 8080:8080 bolingcavalry/hello-quarkus:0.0.1
  • 启动仍旧超快,0.016 秒,四舍五入就是霎时了:
  • 浏览器拜访服务,一切正常:
  • 因为启动命令中增加了 <font color=”blue”>–rm</font> 参数,因而,用 ctrl+ C 退出控制台后,容器会被彻底清理掉
  • 镜像 <font color=”blue”>bolingcavalry/hello-quarkus:0.0.1</font> 曾经上传到 hub.docker.com,您能够随时下载体验

制作镜像(基于惯例 maven 构建后果)

  • 除了上述基于二进制文件制作 docker 镜像,传统的应用惯例 maven 构建后果制作镜像的形式仍然无效,这种镜像也不是齐全没有作用,能够用在近程热部署场景(对于近程热部署,前面有专门的文章细说),接下来咱们试试传统构建镜像的操作
  • 首先是一般的 mvn 编译:

    mvn clean package -U -DskipTests
  • 而后是基于 target 上面的内容制作镜像,quarkus 仍然很贴心的帮咱们筹备好了 Dockerfile 文件(名为 Dockerfile.jvm):

    docker build \
    -f src/main/docker/Dockerfile.jvm \
    -t bolingcavalry/hello-quarkus-jar:0.0.1 .
  • 最初启动镜像试试:

    docker run \
    -i \
    --rm \
    -p 8080:8080 \
    bolingcavalry/hello-quarkus-jar:0.0.1

未完待续

  • 至此,最简略的 quarkus 利用已开发实现,置信您已感触到了这个框架的独特魅力,当然了,如果您是一位 java 后盾开发者,大概率会感觉启动快、省内存这些是精益求精,querkus 与 SpringBoot 的生态差距才是要害,例如:
  • 有哪些配置
  • 依赖注入有没有
  • web 框架好用不
  • CRUD 方不不便
  • 常见中间件反对吗
  • 对于您的和我的诸多疑虑,限于篇幅就不多列举了,然而这些差距的确会影响咱们的决策:生态没建好,别说采纳了,就是学习都没能源
  • 随着学习的开展和深刻,越来越发现自己是多虑了,quarkus 的倒退还是比拟全面的,至多我曾放心的问题都在官网找到了答案,因而,接下来,请随着《quarkus 实战》一起持续精彩的 quarkus 之旅吧,解锁更多精彩实战,欣宸原创,不会辜负您的期待~

欢送关注思否:程序员欣宸

学习路上,你不孤独,欣宸原创一路相伴 …

退出移动版