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

Docker中两微服务调用出现Connection refused问题求助

问题分析与解决方案

首先,你遇到的是Docker容器网络的典型坑——容器内部的localhost和你宿主机的localhost根本不是同一个东西!

为什么浏览器能访问,但微服务调用不行?

  • 当你在浏览器里输入http://localhost:8080/testMicroservicio,这里的localhost指向的是你的宿主机,Docker会把宿主机的8080端口映射到目标微服务容器的对应端口,所以能正常访问。
  • 但你的调用方微服务本身也运行在Docker容器里,当它代码里写localhost时,这个localhost指的是它自己所在的容器,而不是宿主机,自然就会出现连接拒绝的错误。

解决方案(按推荐程度排序)

1. 使用Docker容器名称/服务名作为主机名(最稳定推荐)

Docker默认的桥接网络支持通过容器名称直接解析IP,前提是两个微服务在同一个Docker网络里:

  • 先创建一个专属网络(如果还没创建):
    docker network create my-microservices-net
    
  • 启动两个微服务容器时,都加入这个网络:
    # 启动目标微服务容器,指定名称为target-ms
    docker run --name target-ms --network my-microservices-net -p 8080:8080 你的目标服务镜像名
    
    # 启动调用方微服务容器
    docker run --network my-microservices-net -p 你的端口:你的端口 你的调用方服务镜像名
    
  • 修改代码里的URL:
    private static final String URL_API_INFO = "http://target-ms:8080/testMicroservicio";
    

如果用Docker Compose管理服务,更简单——直接用docker-compose.yml里的服务名称作为主机名即可,Compose会自动创建网络并解析服务名。

2. 用宿主机的局域网IP代替localhost

找到你宿主机的局域网IP(比如Windows用ipconfig,Linux/macOS用ip addr),假设是192.168.3.10,然后修改URL:

private static final String URL_API_INFO = "http://192.168.3.10:8080/testMicroservicio";

这种方法的缺点是宿主机IP可能会变动,不如容器名稳定。

额外注意:你的RestTemplate调用有个小错误

你现在的代码里用了restTemplate.getForObject()却赋值给ResponseEntity,这会导致类型转换错误!getForObject()直接返回响应体对象,而ResponseEntity需要用getForEntity()获取:

// 正确写法1:用getForEntity获取ResponseEntity
ResponseEntity<PruebasMicroservicio[]> response = restTemplate.getForEntity(URL_API_INFO, PruebasMicroservicio[].class);
Arrays.asList(response.getBody()).forEach(info -> log.info("---"+info));

// 正确写法2:直接用getForObject获取响应体
PruebasMicroservicio[] responseBody = restTemplate.getForObject(URL_API_INFO, PruebasMicroservicio[].class);
Arrays.asList(responseBody).forEach(info -> log.info("---"+info));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:50:58