You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Cloud Run部署Scala3+Akka服务启动后异常终止求助

问题根源与解决方案

核心问题分析

  1. sbt run启动方式的缺陷:直接用sbt run作为Docker启动命令时,sbt在完成编译启动流程后会主动退出进程,导致容器随之关闭——即便Akka HTTP服务已经成功启动并监听端口。
  2. sbt-native-packager配置不完整:之前的配置未正确关联主类、传递端口参数,导致容器无法正常监听Cloud Run指定的端口。

方案一:优化Dockerfile,打包可执行JAR运行

1. 修改Dockerfile(分层构建减少镜像体积)

# 构建阶段:使用预配置的Scala+sbt镜像完成编译打包
FROM hseeberger/scala-sbt:11.0.16_1.9.8_3.3.1 AS builder

WORKDIR /app
COPY . .

# 打包包含所有依赖的可执行JAR
RUN sbt assembly

# 运行阶段:使用轻量JRE镜像
FROM openjdk:11-jre-slim

WORKDIR /app
# 从构建阶段复制打包好的JAR
COPY --from=builder /app/target/scala-3.3.1/Test-assembly-*.jar app.jar

EXPOSE 8080
ENV PORT 8080

# 直接运行JAR,避免sbt进程退出问题
CMD ["java", "-jar", "app.jar"]

2. 完善build.sbt与插件配置

在project/plugins.sbt中添加sbt-assembly插件:

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "1.2.0")

修改build.sbt,配置assembly打包规则:

import sbt.Keys.libraryDependencies

ThisBuild / version := "scala-http"
ThisBuild / scalaVersion := "3.3.1"

lazy val root = (project in file("."))
  .settings(
    name := "Test",
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http" % "10.5.0",
      "com.typesafe.akka" %% "akka-actor-typed" % "2.8.5",
      "com.typesafe.akka" %% "akka-stream" % "2.8.5",
      "ch.qos.logback" % "logback-classic" % "1.4.14"
    ),
    // 指定主类
    assembly / mainClass := Some("Main"),
    // 处理依赖冲突
    assemblyMergeStrategy in assembly := {
      case PathList("META-INF", xs @ _*) => MergeStrategy.discard
      case x => MergeStrategy.first
    }
  )

方案二:正确配置sbt-native-packager构建Docker镜像

1. 完善插件与build.sbt配置

在project/plugins.sbt中添加插件:

addSbtPlugin("com.github.sbt" % "sbt-native-packager" % "1.9.8")

修改build.sbt,启用Docker打包插件并配置参数:

import sbt.Keys.libraryDependencies
import com.typesafe.sbt.packager.docker.DockerPlugin.autoImport._

ThisBuild / version := "scala-http"
ThisBuild / scalaVersion := "3.3.1"

// 全局指定主类,避免未使用警告
Global / mainClass := Some("Main")

lazy val root = (project in file("."))
  .enablePlugins(JavaAppPackaging, DockerPlugin)
  .settings(
    name := "Test",
    libraryDependencies ++= Seq(
      "com.typesafe.akka" %% "akka-http" % "10.5.0",
      "com.typesafe.akka" %% "akka-actor-typed" % "2.8.5",
      "com.typesafe.akka" %% "akka-stream" % "2.8.5",
      "ch.qos.logback" % "logback-classic" % "1.4.14"
    ),
    // Docker基础镜像选择轻量JRE
    dockerBaseImage := "openjdk:11-jre-slim",
    // 暴露端口
    dockerExposedPorts := Seq(8080),
    // 设置环境变量传递端口
    dockerEnvVars := Map("PORT" -> "8080"),
    // 自定义启动命令
    dockerEntrypoint := Seq("java", "-jar", s"${name.value}-${version.value}.jar")
  )

2. 构建与部署

执行命令构建镜像:

sbt docker:publishLocal

将构建好的镜像推送到GCP Artifact Registry,再部署至Cloud Run即可。


代码层面优化(可选)

为确保ActorSystem持续运行,避免意外退出,可在Main对象末尾添加等待逻辑:

// 监听ActorSystem终止事件,保持进程活跃
system.whenTerminated.onComplete { _ =>
  logger.info("ActorSystem terminated")
}

Cloud Run部署注意事项

  • 确保Cloud Run服务的端口设置与容器内PORT环境变量一致(默认8080)。
  • 部署镜像需存储在GCP Artifact Registry或可公开访问的镜像仓库中。
  • 部署后查看Cloud Run日志,确认无端口监听失败类错误。

内容的提问来源于stack exchange,提问作者Alexandre Leal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:15:12