跳到正文

Spring Boot ​

Zenavo 识别出的内容 ​

带有 pom.xml 或 build.gradle(.kts) 的仓库会由 zbpack 构建为 Java。当 pom.xml 中有 spring-boot-starter-parent,或者 Gradle 文件中提到 org.springframework.boot 时,识别为 Spring Boot 应用。

MavenGradle
JDKpom.xml 中的 <java.version>、<maven.compiler.source> 或 <maven.compiler.target>build.gradle 中的 sourceCompatibility = … 或 targetCompatibility = …
构建用镜像自带的 Maven 运行 mvn clean dependency:list install -Dmaven.test.skip=true用 Gradle 8.14.3 运行 gradle build -x test
启动java -Dserver.port=$PORT -jar target/*.jarjava -Dserver.port=$PORT -jar build/libs/*.jar

JDK 是 Eclipse Temurin,找不到版本时为 17。测试会被跳过,也不会使用项目中的 mvnw 或 gradlew wrapper。pom.xml 中有 <packaging>war</packaging> 时运行 target/*.war。Zenavo 把 PORT 设为服务的端口(zbpack 构建时是 8080),启动命令会把它作为 server.port 传给 Spring。

要用其他方式启动应用,在 设置 → 构建 → zbpack 选项 中设置 ZBPACK_JAVA_ARGS;启动命令会变成 java 加上它,例如 ZBPACK_JAVA_ARGS=-jar target/app.jar --spring.profiles.active=prod。

部署之前 ​

  • Gradle:关闭 plain jar。 Spring Boot 的 Gradle 插件还会生成 *-plain.jar,它在 build/libs 中排在前面,而且无法运行。在 build.gradle 中加上:

    groovy
    jar {
        enabled = false
    }
  • Gradle:在 zbpack 能读到的地方写明 Java 版本。 zbpack 只读取 build.gradle 中的 sourceCompatibility。用 toolchain 指定版本、或者使用 build.gradle.kts 的项目,会用 JDK 17 构建,较新的代码会失败。请在 build.gradle 中加上 sourceCompatibility = '21',或者使用自己的 Dockerfile(见下文)。

  • 健康检查。 Spring Boot 应用启动需要一些时间。请使用对 /actuator/health 的 HTTP 健康检查(需要 spring-boot-starter-actuator),启动等待设为 60 秒或更长。

连接数据库 ​

Spring 读取的是 JDBC URL,而不是 postgresql:// 连接字符串,所以请用数据库的主机和端口变量拼出一个:

sh
SPRING_DATASOURCE_URL=jdbc:postgresql://${POSTGRESQL_HOST}:${POSTGRESQL_PORT}/zenavo
SPRING_DATASOURCE_USERNAME=postgres
SPRING_DATASOURCE_PASSWORD=${POSTGRESQL_DB_PASSWORD}

MySQL 则是 jdbc:mysql://${MYSQL_HOST}:${MYSQL_PORT}/zenavo,用户为 root,密码为 ${MYSQL_DB_PASSWORD}。从控制台添加的数据库,库名都是 zenavo(数据库)。数据库迁移请用 Flyway 或 Liquibase 在启动时运行,只要其中之一在 classpath 上,Spring Boot 默认就会这样做。

内存 ​

JVM 根据容器的内存决定堆的大小。请为服务设置内存限制,并用一个变量让堆使用其中的大部分:

sh
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75

使用自己的 Dockerfile ​

根目录中的 Dockerfile 会代替 zbpack 使用:适合使用 Gradle wrapper、Kotlin DSL 构建,或者想要更小的运行镜像时。

dockerfile
FROM eclipse-temurin:21-jdk AS build
WORKDIR /src
COPY . .
RUN ./gradlew bootJar --no-daemon

FROM eclipse-temurin:21-jre
COPY --from=build /src/build/libs/*.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]

Maven 项目用 ./mvnw -DskipTests package 构建,并复制 target/*.jar。服务的端口来自 EXPOSE;Spring 默认监听 8080。

常见问题 ​

现象原因
no main manifest attribute, in build/libs/…-plain.jarGradle 还构建了 plain jar。禁用 jar 任务。
invalid target release: 21 或 release version 21 not supportedzbpack 选择了 JDK 17。在 build.gradle 中设置 sourceCompatibility,或在 pom.xml 中设置 <java.version>,或者使用 Dockerfile。
应用还没起来,部署就因健康检查失败启动等待太短。在健康检查中调大它。
OutOfMemoryError,或者高负载时服务重启堆太小,或者超过了内存限制。设置内存限制和 JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75。
Failed to configure a DataSource缺少 SPRING_DATASOURCE_URL,或者它不是 jdbc: URL。

与 Zeabur 无关联。