Akka Http Web 应用程序无法通过 Amazon ECS 中的健康检查
Akka Http web app fails to pass health check in Amazon ECS
更新
我自己回答的
所以我尝试将 docker 化的 Akka Http 示例应用程序部署到 Amazon Elastic Container Service 中。我正在使用 sbt Docker 插件来简化图像创建。
问题: 我在 docker 中的应用程序在本地运行良好,但在由自动缩放组启动时在 EC2 实例中运行不正常。由于某种原因,暴露的端口无法访问。因此健康检查变为 "Unhealthy" 并且容器在启动后 15 秒内被杀死。
我试过的:
- CloudWatch 日志包含正常启动日志:
Server online at http://0.0.0.0:4567/
- 我访问了 EC2 实例并试图在代理启动时卷曲容器。结果是:
curl: (7) Failed to connect to localhost port 4567: Connection refused
I 运行 docker 在 EC2 中手动容器。端口仅在我 运行 和 -p 4567:4567
时有效。但是我 运行 网络模式 "host" 并且我认为不需要端口映射。 ECS 代理在容器启动期间不使用端口映射(在 docker ps
中可观察到)。
我尝试部署两个主机地址绑定:
Http().bindAndHandle(routes, "localhost", 4567) // doesn't work locally on Mac
Http().bindAndHandle(routes, "0.0.0.0", 4567) // works locally in Docker
我用另一个 docker 图像进行了测试以进行比较,它运行良好 (tongueroo/sinatra:latest
):我能够在 EC2 中卷曲它并且它通过了健康检查。
从我的角度来看,ECS 代理没有显示任何有用的信息。
我猜 EXPORT 4567 或 scala/java 绑定到端口出了问题。你有什么想法?
希望你一切都好。
您是否将任务定义配置为绑定端口?这非常重要,因为如果您不公开应用程序端口,您将无能为力。
然后,如果您想从您的机器向容器执行 HTTP 请求,您将需要使用服务发现。 AWS 现在通过 Route 53 为您提供服务发现。但是您可以使用 CONSUL 和 Fabio。
我从某处复制粘贴的 Scala 代码似乎是我自己的错。
旧代码在 ECS 环境中不起作用,但可以在本地无缝运行! :
val serverBinding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, "0.0.0.0", 4567)
serverBinding.onComplete {
case Success(bound) =>
println(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/")
StdIn.readLine() // let it run until user presses return
serverBinding
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
case Failure(e) =>
Console.err.println(s"Server could not start!")
e.printStackTrace()
system.terminate()
}
有效的新固定代码:
val serverBinding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, "0.0.0.0", 4567)
serverBinding.onComplete {
case Success(bound) =>
println(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/ v8")
case Failure(e) =>
Console.err.println(s"Server could not start!")
e.printStackTrace()
system.terminate()
println("Waiting for termination...")
Await.result(system.whenTerminated, Duration.Inf)
println("TERMINATED")
没有阻塞动作,绑定发生后JVM很快退出。
更新
我自己回答的
所以我尝试将 docker 化的 Akka Http 示例应用程序部署到 Amazon Elastic Container Service 中。我正在使用 sbt Docker 插件来简化图像创建。
问题: 我在 docker 中的应用程序在本地运行良好,但在由自动缩放组启动时在 EC2 实例中运行不正常。由于某种原因,暴露的端口无法访问。因此健康检查变为 "Unhealthy" 并且容器在启动后 15 秒内被杀死。
我试过的:
- CloudWatch 日志包含正常启动日志:
Server online at http://0.0.0.0:4567/
- 我访问了 EC2 实例并试图在代理启动时卷曲容器。结果是:
curl: (7) Failed to connect to localhost port 4567: Connection refused
I 运行 docker 在 EC2 中手动容器。端口仅在我 运行 和
-p 4567:4567
时有效。但是我 运行 网络模式 "host" 并且我认为不需要端口映射。 ECS 代理在容器启动期间不使用端口映射(在docker ps
中可观察到)。我尝试部署两个主机地址绑定:
Http().bindAndHandle(routes, "localhost", 4567) // doesn't work locally on Mac
Http().bindAndHandle(routes, "0.0.0.0", 4567) // works locally in Docker
我用另一个 docker 图像进行了测试以进行比较,它运行良好 (
tongueroo/sinatra:latest
):我能够在 EC2 中卷曲它并且它通过了健康检查。从我的角度来看,ECS 代理没有显示任何有用的信息。
我猜 EXPORT 4567 或 scala/java 绑定到端口出了问题。你有什么想法?
希望你一切都好。
您是否将任务定义配置为绑定端口?这非常重要,因为如果您不公开应用程序端口,您将无能为力。
然后,如果您想从您的机器向容器执行 HTTP 请求,您将需要使用服务发现。 AWS 现在通过 Route 53 为您提供服务发现。但是您可以使用 CONSUL 和 Fabio。
我从某处复制粘贴的 Scala 代码似乎是我自己的错。
旧代码在 ECS 环境中不起作用,但可以在本地无缝运行! :
val serverBinding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, "0.0.0.0", 4567)
serverBinding.onComplete {
case Success(bound) =>
println(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/")
StdIn.readLine() // let it run until user presses return
serverBinding
.flatMap(_.unbind()) // trigger unbinding from the port
.onComplete(_ => system.terminate()) // and shutdown when done
case Failure(e) =>
Console.err.println(s"Server could not start!")
e.printStackTrace()
system.terminate()
}
有效的新固定代码:
val serverBinding: Future[Http.ServerBinding] = Http().bindAndHandle(routes, "0.0.0.0", 4567)
serverBinding.onComplete {
case Success(bound) =>
println(s"Server online at http://${bound.localAddress.getHostString}:${bound.localAddress.getPort}/ v8")
case Failure(e) =>
Console.err.println(s"Server could not start!")
e.printStackTrace()
system.terminate()
println("Waiting for termination...")
Await.result(system.whenTerminated, Duration.Inf)
println("TERMINATED")
没有阻塞动作,绑定发生后JVM很快退出。