Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
263 views
in Technique[技术] by (71.8m points)

java - Multi Container Docker app - Connection Refused between containers

So I've got a multi-container application with a front-end, back-end API all sat behind an API gateway. At the moment all apps work fine when booted independently through their respective commands (Java spring apps and an Angular front-end). However, when I start the apps through docker-compose up, none of the apps can communicate with each other (getting a connection refused).

The Gateway is just a basic spring-cloud-gateway starter app which routes requests through to the correct application. This is configured with the following code:

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("api", route -> route.path("/api/**").uri("http://localhost:5001"))
                .route("front-end", route -> route.path("/**").uri("http://localhost:4200"))
                .build();
    }

Error message

After sending a HTTP GET request to http://localhost:5000/api/categories, this error message was produced in the gateway app.

api-gateway_1      | 2021-01-11 00:05:14.514 ERROR 1 --- [or-http-epoll-5] a.w.r.e.AbstractErrorWebExceptionHandler : [d29e1cbf-1]  500 Server Error for HTTP GET "/api/categories"
api-gateway_1      | 
api-gateway_1      | io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: localhost/127.0.0.1:5001
api-gateway_1      |    Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
api-gateway_1      | Error has been observed at the following site(s):
api-gateway_1      |    |_ checkpoint ? org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
api-gateway_1      |    |_ checkpoint ? HTTP GET "/api/categories" [ExceptionHandlingWebHandler]
api-gateway_1      | Stack trace:
api-gateway_1      | Caused by: java.net.ConnectException: finishConnect(..) failed: Connection refused
api-gateway_1      |    at io.netty.channel.unix.Errors.throwConnectException(Errors.java:124) ~[netty-transport-native-unix-common-4.1.55.Final.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.unix.Socket.finishConnect(Socket.java:251) ~[netty-transport-native-unix-common-4.1.55.Final.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.doFinishConnect(AbstractEpollChannel.java:673) ~[netty-transport-native-epoll-4.1.55.Final-linux-x86_64.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.finishConnect(AbstractEpollChannel.java:650) ~[netty-transport-native-epoll-4.1.55.Final-linux-x86_64.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.epollOutReady(AbstractEpollChannel.java:530) ~[netty-transport-native-epoll-4.1.55.Final-linux-x86_64.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:470) ~[netty-transport-native-epoll-4.1.55.Final-linux-x86_64.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378) ~[netty-transport-native-epoll-4.1.55.Final-linux-x86_64.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.55.Final.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.55.Final.jar!/:4.1.55.Final]
api-gateway_1      |    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.55.Final.jar!/:4.1.55.Final]
api-gateway_1      |    at java.base/java.lang.Thread.run(Unknown Source) ~[na:na]

Attempted steps/more info

I have tried defining my own network but this does not change anything so I have left the containers on the default network created upon running docker-compose up.

I can hit each app independently via cURL or through Postman and I can access the front-end through the browser.

Docker-Compose.yml

version: "3"

services:
  api:
    build: ./api
    ports:
      - "5001:5001"
  gateway:
    build: ./gateway
    ports:
      - "5000:5000"
  frontend:
    build: ./frontend
    ports:
      - "4200:80"

Dockerfiles

Gateway

FROM openjdk:11 as build

COPY . .

RUN ./gradlew build --parallel

FROM openjdk:11-jre-slim as runtime

COPY --from=build /build/libs/gateway-0.0.1-SNAPSHOT.jar /usr/app/

WORKDIR /usr/app

ENTRYPOINT ["java", "-jar", "gateway-0.0.1-SNAPSHOT.jar"]

API

FROM openjdk:11 as build

COPY . .

RUN ./gradlew build --parallel

FROM openjdk:11-jre-slim as runtime

COPY --from=build /build/libs/api-0.0.1-SNAPSHOT.jar /usr/app/

WORKDIR /usr/app

ENTRYPOINT ["java", "-jar", "api-0.0.1-SNAPSHOT.jar"]

Front-end

FROM node:12.7-alpine AS build

WORKDIR usr/src/app

COPY package.json package-lock.json ./

RUN npm install

COPY . .

RUN npm run build

FROM nginx:1.17.1-alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /usr/src/app/dist/awards-frontend /usr/share/nginx/html

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Thanks to @DavidMaze for making me notice this.

Seems like I was being a bit of a fool. My apps are sending network requests to localhost. This works fine when they are all running outside of a container. When in a container they need to be sending requests to the names of the other containers. For example:

app_1 runs on port 8080 app_2 runs on port 5000

When running outside of docker, app_1 could send a network request to app_2 via http://localhost:5000. This does not work inside of a container as nothing is running on localhost:5000 in that container. Instead, it will need to reference the other container eg: http://app_2:5000.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.7k users

...