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

Docker容器间Java Spring Boot应用Rest API通信失败求助

容器间通信失败问题排查与解决

问题描述

本地控制台运行两个Spring Boot应用时正常,Postman调用端点也正常,但Docker化部署后,访问http://localhost:8080/send出现错误:

I/O error on POST request for "http://localhost:8081/processString": Connection refused.

代码与配置信息

LogonPageApplication(端口8080)

@SpringBootApplication
@RestController
public class LogonPageApplication {
    private static final String PROCESS_STRING_URL = "http://localhost:8081/processString";

    public static void main(String[] args) {
        SpringApplication.run(LogonPageApplication.class, args);
    }

    @GetMapping("/send")
    public String test() {

        String responseBody = "";
        try {
            RestTemplate restTemplate = new RestTemplate();

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            String requestBody = "{testttgfvrdf}";
            HttpEntity<String> httpEntity = new HttpEntity<>(requestBody, headers);

            ResponseEntity<String> response = restTemplate.exchange(PROCESS_STRING_URL, HttpMethod.POST, httpEntity, String.class);

            responseBody = response.getBody();
        } catch (Exception e) {
            return e.getMessage();
        }

        return "Main Page\n" + "Response from /processString: " + responseBody;
    }

}

AcceptMessageApplication(端口8081)

@SpringBootApplication
@RestController
public class AcceptMessageApplication {

    public static void main(String[] args) {
        SpringApplication.run(AcceptMessageApplication.class, args);
    }

    @PostMapping("/processString")
    public String processString(@RequestBody String inputString) {
        return "Processed string: " + inputString;
    }

}

Dockerfile示例(两个应用的Dockerfile需对应自身jar包)

FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/AcceptMessage-0.0.1-SNAPSHOT.jar /app/AcceptMessage-0.0.1-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "AcceptMessage-0.0.1-SNAPSHOT.jar"]

注:LogonPage的Dockerfile需将COPY和CMD中的jar包名称替换为自身项目的jar,比如LogonPage-0.0.1-SNAPSHOT.jar

docker-compose.yml

version: '3'
services:
  appacc:
    build:
      context: AcceptMessage
      dockerfile: Dockerfile
    ports:
      - "8081:8080"
    networks:
      - my-network
  applog:
    build:
      context: LogonPage
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    networks:
      - my-network
networks:
  my-network:

# docker-compose build
# docker-compose up

问题原因

容器内的localhost指向容器自身,而非宿主机。当applog容器尝试访问http://localhost:8081时,实际是在访问自己容器的8081端口,而该端口并未对外开放,因此出现连接拒绝错误。

Docker Compose创建的自定义网络中,容器之间可以通过服务名称直接通信,无需使用宿主机的端口映射。appacc服务的内部端口是8080(容器自身运行的端口),宿主机的8081端口只是对外映射的端口,容器间通信不需要走这个映射端口。

解决方案

  1. 修改LogonPageApplication中的请求地址
    将PROCESS_STRING_URL的值改为http://appacc:8080/processString,其中appacc是docker-compose.yml中定义的服务名称,容器会自动解析该名称到对应的容器IP地址:

    private static final String PROCESS_STRING_URL = "http://appacc:8080/processString";
    
  2. 修正LogonPage的Dockerfile
    确保LogonPage的Dockerfile中COPY和CMD指向的是自身项目的jar包,避免因jar包名称错误导致容器无法启动:

    FROM openjdk:17-jdk-slim
    WORKDIR /app
    COPY target/LogonPage-0.0.1-SNAPSHOT.jar /app/LogonPage-0.0.1-SNAPSHOT.jar
    EXPOSE 8080
    CMD ["java", "-jar", "LogonPage-0.0.1-SNAPSHOT.jar"]
    
  3. 重新构建并启动服务
    执行以下命令重新构建镜像并启动容器:

    docker-compose build
    docker-compose up
    

完成以上步骤后,访问http://localhost:8080/send即可正常获取appacc服务的响应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 23:45:18