将Spring Boot 3应用的JAR部署并运行在Open Liberty上
Open Liberty 23.0.0.9现已发布支持Spring Boot 3版本应用程序运行的 springBoot-3.0 功能。
过去也支持将Spring Boot应用程序打包成WAR文件进行部署。通过使用springBoot-3.0功能,还可以支持以JAR文件方式运行。
在这篇文章中,我们将尝试将使用Spring Boot 3实现的Web应用的JAR部署到Open Liberty并让其运行。
在本文中所使用的组件
本文提供以下的组件版本进行了操作确认。
由于不同版本的每个组件可能无法正常工作,因此建议您在正式投入使用之前先在本地进行操作确认。
$ java -version
openjdk version "17.0.8" 2023-07-18
IBM Semeru Runtime Open Edition 17.0.8.0 (build 17.0.8+7)
Eclipse OpenJ9 VM 17.0.8.0 (build openj9-0.40.0, JRE 17 Mac OS X amd64-64-Bit Compressed References 20230718_503 (JIT enabled, AOT enabled)
OpenJ9 - d12d10c9e
OMR - e80bff83b
JCL - 77b0f754805 based on jdk-17.0.8+7)
应用程序准备
此文档将在事先准备好的 Web 应用程序的情况下进行实施。请使用 Spring Initializer 或类似工具创建模板并进行实现。
为使其在 Open Liberty 上运行,请至少在依赖关系中包含 spring-boot-starter-web 作为运行 Web 应用程序所需的依赖。以下是示例的 pom.xml 文件。
无论是在Open Liberty上部署还是其他情况下,应用程序本身都不需要特定的设置。
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<!-- Spring Boot 3系を使用 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.4</version>
<relativePath/>
</parent>
<!-- JARファイルは {artifactId}-{version}.jar という名前で出力される -->
<groupId>com.example</groupId>
<artifactId>liberty-sb-web</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>liberty-sb-web</name>
<properties>
<java.version>17</java.version>
</properties>
<!-- 依存ライブラリ -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Mavenビルドで使用するプラグイン -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!-- 他の設定値は記載省略 -->
</project>
打开Liberty的设置
最重要的一点从这里开始。我们需要在Open Liberty的配置文件 src/main/liberty/config/server.xml 中添加用于运行Spring Boot的JAR文件的配置。
增加功能
我宣布Open Liberty拥有两个功能。
springBoot-3.0 … Spring BootアプリのJARファイルを起動する機能を提供
servlet-6.0 … Spring Boot Starter Webが依存するServlet APIを提供
<?xml version="1.0" encoding="UTF-8"?>
<server description="Spring Boot WebApp on Liberty">
<!-- フィーチャー -->
<featureManager>
<feature>springBoot-3.0</feature>
<feature>servlet-6.0</feature>
</featureManager>
<!-- 他の設定値は記載省略 -->
</server>
Spring Boot相关设置
(1)在 springBootApplication 的元素中指定要部署的 Spring Boot 应用程序 JAR 文件的位置。请注意,在后续步骤中,将会将该 JAR 文件转换为经过优化的 Open Liberty JAR 文件,因此需要指定转换后的文件名。
在示例中,我们指定的不是使用 Maven 生成的 JAR 文件 liberty-sb-web-0.0.1-SNAPSHOT.jar,而是经过优化后的 thin-liberty-sb-web-0.0.1-SNAPSHOT.jar。
(2) 接下来,我们要添加在Web应用程序中通过HTTP进行公开的配置。当在Open Liberty中公开Spring Boot应用时,将端口号9090指定为httpEndpoint元素。
如果使用Open Liberty默认的9080端口,请参考文档,因为JAR文件的部署位置可能与本文不同。
<?xml version="1.0" encoding="UTF-8"?>
<server description="Spring Boot WebApp on Liberty">
<!-- (1) Spring Boot 3 application -->
<springBootApplication location="thin-liberty-sb-web-0.0.1-SNAPSHOT.jar" name="liberty-sb-web" />
<!-- (2) HTTP endpoint -->
<httpEndpoint id="defaultHttpEndpoint" host="*" httpPort="9090" />
<!-- 他の設定値は記載省略 -->
</server>
将应用程序部署至Open Liberty
最后是部署步骤。重新构建了针对Open Liberty优化的JAR文件后,进行部署。优化处理将使用Open Liberty内置的springBootUtility。
为了一次性执行应用程序JAR文件的构建、优化和部署到Open Liberty,我们将其容器化并运行在Docker容器中。下面的示例Dockerfile使用多阶段构建,同时复制中间生成的结果,以创建已部署的应用程序容器镜像。
# Build Spring Boot 3 JAR
FROM docker.io/library/maven:3.9-ibm-semeru-17-focal AS builder
WORKDIR /usr/local/builder
COPY . .
RUN mvn clean package -DskipTests -B -ntp
# Optimize Spring Boot app to Liberty
FROM icr.io/appcafe/open-liberty:23.0.0.9-full-java17-openj9-ubi AS staging
COPY --chown=1001:0 --from=builder /usr/local/builder/target/liberty-sb-web-0.0.1-SNAPSHOT.jar /staging/fat-liberty-sb-web-0.0.1-SNAPSHOT.jar
RUN springBootUtility thin \
--sourceAppPath=/staging/fat-liberty-sb-web-0.0.1-SNAPSHOT.jar \
--targetThinAppPath=/staging/thin-liberty-sb-web-0.0.1-SNAPSHOT.jar \
--targetLibCachePath=/staging/lib.index.cache
# Deploy optimized Spring Boot app to Liberty
FROM icr.io/appcafe/open-liberty:23.0.0.9-kernel-slim-java17-openj9-ubi
COPY --chown=1001:0 --from=builder /usr/local/builder/src/main/liberty/config/server.xml /config/server.xml
RUN features.sh
COPY --chown=1001:0 --from=staging /staging/lib.index.cache /lib.index.cache
COPY --chown=1001:0 --from=staging /staging/thin-liberty-sb-web-0.0.1-SNAPSHOT.jar /config/apps/
RUN configure.sh
使用Podman构建容器镜像。如果使用Docker作为容器运行时,则将podman替换为docker即可。
$ podman build -t liberty-sb-web:v1 .
检查工作状态
使用构建的容器映像启动应用程序。Spring Boot和Open Liberty的日志会混合在一起,但如果输出了“Started”日志,则说明已成功启动。
$ podman run --rm --name liberty -p 9090:9090 liberty-sb-web:v1
Launching defaultServer (Open Liberty 23.0.0.9/wlp-1.0.81.cl230920230904-1158) on Eclipse OpenJ9 VM, version 17.0.8+7 (en_US)
[AUDIT ] CWWKE0001I: The server defaultServer has been launched.
...
2023-10-01T12:44:59.204Z INFO 1 --- [ecutor-thread-2] com.example.LibertySbWebApplication : Starting LibertySbWebApplication using Java 17.0.8 with PID 1 (/opt/ol/wlp/usr/servers/defaultServer/apps/thin-liberty-sb-web-0.0.1-SNAPSHOT.jar started by default in /opt/ol/wlp/output/defaultServer)
2023-10-01T12:44:59.225Z INFO 1 --- [ecutor-thread-2] com.example.LibertySbWebApplication : No active profile set, falling back to 1 default profile: "default"
[AUDIT ] CWWKT0016I: Web application available (default_host): http://0193c36e412b:9090/
2023-10-01T12:45:00.701Z INFO 1 --- [ecutor-thread-5] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1373 ms
2023-10-01T12:45:01.394Z INFO 1 --- [ecutor-thread-2] com.example.LibertySbWebApplication : Started LibertySbWebApplication in 2.561 seconds (process running for 4.059)
[AUDIT ] CWWKZ0001I: Application liberty-sb-web started in 3.028 seconds.
[AUDIT ] CWWKF0012I: The server installed the following features: [servlet-6.0, springBoot-3.0].
[AUDIT ] CWWKF0011I: The defaultServer server is ready to run a smarter planet. The defaultServer server started in 4.063 seconds.
参考文件
-
- Spring Bootアプリケーションのデプロイ方法
- springBoot-3.0フィーチャー
以上。