Docker:java.net.ConnectException:连接被拒绝-在端口8083上运行的应用程序无法访问端口3000上的其他应用程序

时间:2019-02-14 14:24:03

标签: rest spring-boot docker dockerfile

我必须在Spring Boot中使用外部rest API(使用restTemplate.exchange)。我的其余API在端口8083上使用URL http://localhost:8083/myrest(Docker命令:docker run -p 8083:8083 myrest-app)运行

外部API以公共docker映像的形式提供,在以下命令下运行后,我可以在本地拉并运行它。

 docker pull dockerExternalId/external-rest-api docker
    run -d -p 3000:3000 dockerExternalId/external-rest-api

a)如果我直接在Chrome中输入外部Rest API URL,例如http://localhost:3000/externalrestapi/testresource,那么我将获得有效的JSON数据。

b)如果我使用eclipse(春季启动应用程序)中的myrest应用程序调用它,我仍然可以获得有效的JSON响应。 (我正在使用Windows平台进行测试)

c)但是,如果我在Docker上运行它并执行myrest服务(例如http://localhost:8083/myrest),那么我将面临java.net.ConnectException: Connection refused

更多详细信息:

org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://localhost:3000/externalrestapi/testresource": Connection refused (Connection refused); nested exception is java.net.ConnectException: Connection refused (Connection refused)

PS-我正在Windows上使用Docker。

2 个答案:

答案 0 :(得分:3)

#问题

您使用:

docker run -p 8083:8083 myrest-app

但是您需要像这样运行:

docker run --network "host" --name "app" myrest-app

因此,将标记--network与值host一起传递将使您的容器可以访问您的计算机网络。

请忽略我的第一种方法,而是使用一种更好的替代方法,即不将容器暴露给整个主机网络...可以使其正常工作,但这不是最佳实践。

更好的选择

创建两个容器都将使用的网络:

docker network create external-api

然后使用标记--network external-api运行两个容器。

docker run --network "external-api" --name "app" -p 8083:8083 myrest-app

docker run -d --network "external-api" --name "api" -p 3000:3000 dockerExternalId/external-rest-api

仅当您要从计算机浏览器访问它时,才需要使用标志-p来发布api容器的端口,否则就不要使用它们了,因为不需要它们2个容器在external-api网络中进行通信。

  

提示:不需要docker pull,一旦docker run,它将在您的计算机中找不到图像时尝试拉该图像。   让我知道怎么回事...

调用外部API

因此,在两种解决方案中,我都添加了--name标志,以便我们可以访问网络中的另一个容器。

因此,要从我的rest应用访问外部api,您需要使用网址http://api:3000/externalrestapi/testresource

请注意,我是如何用localhost替换api的,该--name与您的外部api的docker run命令中的import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'log' }) export class LogPipe implements PipeTransform { transform(value: any, args?: any): any { console.log(value); return null; } } 标志的值匹配。

答案 1 :(得分:1)

如果您尝试访问myrest-app,请从您的http://localhost:3000/externalrestapi/testresource容器中尝试访问同一3000的{​​{1}}端口。

因为每个容器是一个单独运行的操作系统,并且具有自己的网络接口,文件系统等。

myrest-app container

您可以通过3种方式从另一个容器访问API。

  1. 提供外部主机的IP地址(而不是Docker is all about Isolation)(即运行docker的计算机的IP地址)
  2. Create一个docker网络和attach这两个容器。然后,您可以提供localhost而不是container_name
  3. 启动容器时使用--link(已弃用)