写点什么

Vert.x 教程 (而):如何打包一个 Vert.x 应用

作者:Kevin_913
  • 2023-11-02
    广东
  • 本文字数:2168 字

    阅读完需:约 7 分钟

这篇文章将讲解如何打包 Vert.x 应用。

依赖

  • 添加maven-compiler-plugin,指定 java 编译版本。


<plugin>  <artifactId>maven-compiler-plugin</artifactId>  <version>${maven-compiler-plugin.version}</version>  <configuration>    <release>17</release>  </configuration></plugin>
复制代码


  • 添加maven-shade-plugin,指定 VertX Launcher 和 MainVerticle,在有额外依赖的时候,过滤掉依赖包里面的一些版本文件,META-INF/*.RSAMETA-INF/*.DSAMETA-INF/*.SF,不然会导致一些 java 版本冲突的问题。


<main.verticle>com.kevin.sample.vertx.demo.MainVerticle</main.verticle><launcher.class>io.vertx.core.Launcher</launcher.class>
复制代码


<plugin>  <artifactId>maven-shade-plugin</artifactId>  <version>${maven-shade-plugin.version}</version>  <executions>    <execution>      <phase>package</phase>      <goals>        <goal>shade</goal>      </goals>      <configuration>        <transformers>          <transformer            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">            <manifestEntries>              <Main-Class>${launcher.class}</Main-Class>              <Main-Verticle>${main.verticle}</Main-Verticle>            </manifestEntries>          </transformer>          <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>        </transformers>        <outputFile>${project.build.directory}/${project.artifactId}-${project.version}-fat.jar        </outputFile>        <filters>          <filter>            <artifact>*:*</artifact>            <excludes>              <exclude>META-INF/*.SF</exclude>              <exclude>META-INF/*.DSA</exclude>              <exclude>META-INF/*.RSA</exclude>            </excludes>          </filter>        </filters>      </configuration>    </execution>  </executions></plugin>
复制代码

打包成 Docker image

这里会用基于不同的 jvm 去打包,一种是 HotSpot VM,JIT 模式;一种是 GraalVM,AOT 模式,JIT 和 AOT 的区别参考这篇文章


  • 基于 openjdk 去创建 Docker image,生成的 image 大小 500M 左右。

  • 执行./mvnw clean package在 target 目录下面生成*-fat.jar。

  • 创建 Dockerfile


FROM openjdk:17
ARG workspace
COPY $workspace/target/*-fat.jar /app/app.jarWORKDIR /app
ENTRYPOINT ["java","-jar", "./app.jar" ]
复制代码


  • 基于 GraalVM 的 native image 打包,需要注意两点。

  • 由于 GraalVM 采用的是 AOT 模式,提前将所有代码编译成机器码,而 Java 中的一些反射,动态代理也需要提前分析生成,GraalVM 提供了一个参数-agentlib:native-image-agent=config-output-dir=./src/main/resources/META-INF/native-image,将会分析生成对应的 jni,反射,代理等配置放在指定的目录,同时为了简化运行命令,可以在相同的目录创建native-image.properties文件,指定对应的文件地址,以及 MainVerticle 和可执行程序名称。下面是一个 native-image.properties 示例。

Args =\--report-unsupported-elements-at-runtime \-H:ReflectionConfigurationResources=${.}/reflect-config.json \-H:JNIConfigurationResources=${.}/jni-config.json \-H:ResourceConfigurationResources=${.}/resource-config.json \-H:Class=com.kevin.sample.vertx.demo.MainVerticle \-H:Name=demo--initialize-at-run-time=\io.netty.handler.codec.compression.ZstdOptions
复制代码
  • 通过 mulitple stage 的方式减少 Docker iamge 的大小,生成的 image 大小 50M 左右,需要选择一个包含 glibc 或者 musl 的 alpine 或者 scratch 作为最终基础镜像。

  • 基于*-fat.jar 去创建 Docker image。

  • 执行./mvnw clean package在 target 目录下面生成*-fat.jar。

  • 创建 Dockerfile

## Stage 1 : build with maven builder image with native capabilitiesFROM container-registry.oracle.com/graalvm/native-image:17 AS build
ARG workspace
COPY $workspace/target/*-fat.jar /app/app.jarWORKDIR /appRUN native-image -jar app.jar
## Stage 2 : create the final image, need a glibc or musl alpineFROM frolvlad/alpine-glibcCOPY --from=build /app/demo /app/applicationEXPOSE 8888WORKDIR /app/ENTRYPOINT [ "/app/application" ]
复制代码
  • 完整打包方式创建 Docker image,可以用在 CI/CD 流程当中。

  • 添加 Maven 依赖。

  • 添加 DockerFile

## Stage 1 : build with maven builder image with native capabilitiesFROM container-registry.oracle.com/graalvm/native-image:17 AS build
ARG workspace
USER rootCOPY $workspace/mvnw /code/mvnwCOPY $workspace/.mvn /code/.mvnCOPY $workspace/pom.xml /code/WORKDIR /code
COPY $workspace/src /code/srcRUN ./mvnw package -DskipTests
## Stage 2 : create the final image, need a glibc or musl alpineFROM frolvlad/alpine-glibcCOPY --from=build /code/target/demo /app/application
EXPOSE 8888WORKDIR /app/ENTRYPOINT [ "/app/application" ]
复制代码


发布于: 刚刚阅读数: 5
用户头像

Kevin_913

关注

纸上得来终觉浅,绝知此事要躬行。 2019-02-25 加入

专注于代码和设计15+年。 主要涉及Java,Golang,云平台。

评论

发布
暂无评论
Vert.x 教程 (而):如何打包一个 Vert.x 应用_教程_Kevin_913_InfoQ写作社区