如何在另一个akka http路由中调用一个akka http路由使用akka http客户端使用docker?

y53ybaqx  于 2022-11-23  发布在  Docker
关注(0)|答案(1)|浏览(201)

我有两个Akka HTTP服务器,分别运行在Docker和不同的端口上
我已经使用sbt本地软件包管理器来创建文档文件
下面是projectA的docker-compose

akkahttpservice:
    image: projectA-service:0.0.1
    container_name: projectA-service-container
    ports:
      - "8085:8085"

这里是项目B的停靠器-组成

akkahttpservice:
    image: projectB-service:0.0.1
    container_name: projectB-service-container
    ports:
      - "8083:8083"

这是docker ps的输出

CONTAINER ID   IMAGE                         COMMAND                  CREATED         STATUS          PORTS                                                                                  NAMES
71a58c080e7c   projectA-service:0.0.1   "/opt/docker/bin/not…"   5 minutes ago   Up 5 minutes    8084/tcp, 0.0.0.0:8085->8085/tcp, :::8085->8085/tcp                                    projectA-service-container
c08f5700ce3d   projectB-service:0.0.1          "/opt/docker/bin/int…"   22 hours ago    Up 28 minutes   0.0.0.0:8083->8083/tcp, :::8083->8083/tcp                                              projectB-service-container

我想使用akka http客户端在项目A中调用项目B路由
这是项目B的路由

def getAdminToken: server.Route =
    path("get-admin-token") {
    post {
  entity(as[JsValue]) {
            json =>
              val userName = json.asJsObject.fields("userName").convertTo[String]
              val userPwd = json.asJsObject.fields("userPwd").convertTo[String]
complete("got the details")
        }
   }
}

下面是我想在其中调用projectB route的projectA的代码

def addUserInKeyCloak: server.Route = {
    path("add-user-in-keycloak") {
      post {
        entity(as[NotaryUser]) {
          notaryUser =>
            val adminUrl = "http://0.0.0.0:8083/get-admin-token"
        val jsonStr =
          s"""{
             |     "userName":"admin",
             |   "userPwd":"admin"
             |  }""".stripMargin
val request = HttpRequest(HttpMethods.POST, adminUrl, Nil, HttpEntity(ContentTypes.`application/json`, jsonStr.stripMargin.parseJson.toString()))
        val responseFuture = Http(context.system).singleRequest(request)
        complete("result from future")
            
        }
      }
    }
  }

我已经试过了

val adminUrl = "http://0.0.0.0:8083/get-admin-token"

得到一个异常

Tcp command [Connect(0.0.0.0:8083,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused (akka.stream.StreamTcpException: Tcp command [Connect(0.0.0.0:8083,None,List(),Some(10 seconds),true)] failed because of java.net.ConnectException: Connection refused)

我尝试使用其他URL

val adminUrl = "http://projectB-service-container:8083/get-admin-token"

然后我得到了另一个例外

Tcp command [Connect(docker-interpret-auth-container:8083,None,List(),Some(10 seconds),true)] failed because of java.net.UnknownHostException: projectB-service-container (akka.stream.StreamTcpException: Tcp command [Connect(projectB-service-container:8083,None,List(),Some(10 seconds),true)] failed because of java.net.UnknownHostException: projectB-service-container)

在不使用docker的情况下,代码运行良好。在使用docker-compose的docker上运行这两个代码时,会发生以上所有异常
当使用docker-compose在docker上运行时,上面的代码也可以很好地与postman和curl一起工作

nom7f22z

nom7f22z1#

尝试使用主机0.0.0.0的路由只会尝试向同一容器内的端口发出请求,而这不是您要查找的内容。您的错误是Connection refused,因为应用程序在不同的容器中运行,因此它们无法使用主机0.0.0.0相互访问。要使用Docker Compose访问另一个正在运行的容器,将服务的名称引用为主机,如下面的docker-compose.yml

version: "3.3"
services:
  akkahttpservicea:
    image: projectA-service:0.0.1
    container_name: projectA-service-container
    ports:
      - "8085:8085"
  akkahttpserviceb:
    image: projectB-service:0.0.1
    container_name: projectB-service-container
    ports:
      - "8083:8083"

例如,在projectA中,使用

val adminUrl = "http://akkahttpserviceb:8083/get-admin-token"

相关问题