Docker 的 NestJS 微服务问题

时间:2021-03-06 22:23:08

标签: node.js docker nestjs

我正在尝试创建 NestJS 微服务并使用 docker 容器通过客户端网关访问它。当我在本地运行它时,它工作正常,但是当我将它部署在 docker 上时,它给了我以下错误。我有两个不同的 docker 文件,一个用于网关,一个用于微服务。

`[Nest] 1 - 03/06/2021, 10:11:19 PM [ExceptionsHandler] connect ECONNREFUSED 127.0.0.1:4000 +19833ms
Error: connect ECONNREFUSED 127.0.0.1:4000
at TCPConnectWrap.afterConnect [as oncomplet]`

Dockerfile.gateway

`FROM node:12.18-alpine
RUN mkdir -p /custom-root
WORKDIR /custom-root
COPY ./package.json .
COPY ./nest-cli.json .
COPY ./tsconfig.json .
COPY ./tsconfig.build.json .
COPY ./apps/gateway-client/. ./apps/gateway-client/.
RUN npm install -g @nestjs/cli
RUN npm install
RUN npm run build gateway-client
EXPOSE 3001
CMD [ "node", "./dist/apps/gateway-client/main.js" ]`

服务泊坞窗文件

`FROM node:12.18-alpine
RUN mkdir -p /custom-root
WORKDIR /custom-root
COPY ./package.json .
COPY ./nest-cli.json .
COPY ./tsconfig.json .
COPY ./tsconfig.build.json .
COPY ./apps/service-customer/. ./apps/service-customer/.
RUN npm install -g @nestjs/cli
RUN npm install
RUN npm run build service-customer
EXPOSE 4000
CMD [ "node", "./dist/apps/service-customer/main.js" ]`

这里是服务文件 TCP 连接

async function bootstrap() {
  const { SERVICE_CUSTOMER_PORT, SERVICE_CUSTOMER_HOST } = process.env;
  const port = SERVICE_CUSTOMER_PORT || 4000;
  const host = SERVICE_CUSTOMER_HOST || '0.0.0.0';
  const app = await NestFactory.createMicroservice(CustomerModule, {
    transport: Transport.TCP,
    options: {
      host,
      port
    },
  });
  app.listen(() => logger.log(`Customer Microservice is listening at ${port} host -> ${host}`));
}
bootstrap();

这是网关代码

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const { GATEWAY_PORT } = process.env;
  const port = GATEWAY_PORT || 3001
  await app.listen(port);
}
bootstrap();

请帮忙

2 个答案:

答案 0 :(得分:0)

您正在尝试通过 localhost 连接到另一个容器,这就是您获得 ECONNREFUSED 127.0.0.1:4000 的原因。默认情况下,容器在隔离的命名空间中运行,包括网络。端口 4000 上没有任何内容侦听客户端容器的命名空间。

因此,要使其发挥作用,您有两个选择:

  1. 确保两个容器共享同一个网络并使用容器的服务名进行连接。

    version: "3.9"
    services:
    
      client:
        image: client
        links:
          - "server:server"
      server:
        image: server
    

    在此之后,客户端容器将有一个 DNS 名称 server,因此到 server:4000 而不是 localhost:4000 的连接将起作用。

  2. 将两个容器连接到 host 网络。这不是推荐的方法

答案 1 :(得分:0)

请注意,您正在使用 NestJS 创建微服务和 api 网关。为了分别容器化它们,您需要创建单独的混合应用程序以通过 http 进行通信。请查看Expose normal http endpoint in NestJS Microservices

这是一篇有助于拆分应用程序的文章。
How to split Nest.js microservices into separate projects?

之后,您可以将所有这些不同的混合应用程序(通过 http 的微服务)容器化,并在您的 api 网关或任何可以进行通信的通道上配置它们。