rest - Docker:java.net.ConnectException:连接被拒绝 - 在端口 8083 上运行的应用程序无法访问端口 3000 上的其他应用程序
问题描述
我必须使用 Spring Boot 使用外部休息 API(使用 restTemplate.exchange)。我的 REST 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(Spring Boot 应用程序)的 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。
解决方案
# 问题
你运行:
docker run -p 8083:8083 myrest-app
但是你需要像这样运行:
docker run --network "host" --name "app" myrest-app
--network
因此,传递带有值的标志host
将允许您的容器访问您的计算机网络。
请忽略我的第一种方法,而是使用不将容器暴露给整个主机网络的更好的替代方法......可以使它工作,但不是最佳实践。
更好的选择
创建一个供两个容器使用的网络:
docker network create external-api
然后使用 flag 运行两个容器--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,您需要使用 url http://api:3000/externalrestapi/testresource
。
请注意我如何替换localhost
为与您的外部 api 的 docker run 命令中的 flagapi
值匹配的值。--name
推荐阅读
- oracle-ebs - Oracle EBS 直接数据库访问
- redis - redis sentinel 没有将 +sdown 提升为 +odown
- c# - Unity3D:如何从附加到预制件的其他脚本中调用一个脚本中的函数?
- javascript - ajax成功后返回空值?
- macos - 如何将拖放文件列表传递给 install4J 启动器?
- google-cloud-platform - 从 Java 访问 Bigquery IAM
- angular - Nativscript getRootView()不起作用
- c - 为什么当前宏会返回 14 的值?
- bash - 找不到简单变量赋值的 Bash 命令
- matplotlib - Matplotlib 图未显示在 Jupyter 笔记本第一个单元格的输出小部件中