如何修复“14 UNAVAILABLE:目标 dns 名称解析失败:http://sample-service:40000”GRPC + Docker 错误

问题描述 投票:0回答:3

我在 Docker 容器中部署了一个 Nest.js gRPC 服务器和一个客户端,并使用以下 docker 命令,

客户端(API网关):

docker run -dit -p 3000:3000 --hostname ${{ env.IMAGE_NAME }} --name ${{ env.IMAGE_NAME }} --network web_server ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{env.TAG}}

客户端环境

IMAGE_NAME=api-gateway

服务器(问题服务):

docker run -dit -p 40000:40000 --hostname ${{ env.IMAGE_NAME }} --name ${{ env.IMAGE_NAME }} --network web_server ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{env.TAG}}

服务器环境

IMAGE_NAME=question-service

服务器(问题服务)的Main.ts是这样的,

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport } from '@nestjs/microservices';
import { join } from 'path';

const microserviceOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../src/question/question.proto'),
    url: '0.0.0.0:40000',
  },
};

async function bootstrap() {
  const app = await NestFactory.createMicroservice(
    AppModule,
    microserviceOptions,
  );
  app.listen();
}
bootstrap();

客户端集成是这样的, grpc.option.ts:

import { ClientOptions, Transport } from '@nestjs/microservices';
import { join } from 'path';

export const microserviceOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../question/question.proto'),
    url: 'question-service:40000',
  },
};

问题.service.ts:

import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { Client, ClientGrpc } from '@nestjs/microservices';
import { CreateQuestionInput } from './dto/create-question.input';
import { QuestionGrpcService } from './grpc.interface';
import { microserviceOptions } from './grpc.option';
import { Question } from './entities/question.entity';
import { firstValueFrom } from 'rxjs';

@Injectable()
export class QuestionService implements OnModuleInit {
  private logger = new Logger('QuestionService');
  @Client(microserviceOptions)
  private client: ClientGrpc;

  private questionGrpcService: QuestionGrpcService;

  onModuleInit() {
    this.questionGrpcService =
      this.client.getService<QuestionGrpcService>('QuestionService');
  }

  createQuestion(createQuestionInput: CreateQuestionInput) {
    return this.questionGrpcService.createQuestion(createQuestionInput);
  }

  async getQuestions(): Promise<Question[]> {
    let questions = [];
    const res = await firstValueFrom(this.questionGrpcService.getQuestions({}));
    questions = res.questionsResposes;
    return questions;
  }
}

但是当我调用 api-gateway 的 graphql enpoint 来获取所有问题时,它会返回以下错误,

{
  "errors": [
    {
      "message": "14 UNAVAILABLE: Name resolution failed for target dns:http://question-service:40000",
      "locations": [
        {
          "line": 16,
          "column": 3
        }
      ],
      "path": [
        "question"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "code": 14,
          "details": "Name resolution failed for target dns:http://question-service:40000",
          "metadata": {},
          "stacktrace": [
            "Error: 14 UNAVAILABLE: Name resolution failed for target dns:http://question-service:40000",
            "    at Object.callErrorFromStatus (/node_modules/@grpc/grpc-js/build/src/call.js:31:19)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client.js:190:52)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:365:141)",
            "    at Object.onReceiveStatus (/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:328:181)",
            "    at /node_modules/@grpc/grpc-js/build/src/call-stream.js:188:78",
            "    at processTicksAndRejections (internal/process/task_queues.js:79:11)",
            "for call at",
            "    at ServiceClientImpl.makeUnaryRequest (/node_modules/@grpc/grpc-js/build/src/client.js:160:30)",
            "    at ServiceClientImpl.getQuestions (/node_modules/@grpc/grpc-js/build/src/make-client.js:105:19)",
            "    at Observable._subscribe (/node_modules/@nestjs/microservices/client/client-grpc.js:177:39)",
            "    at Observable._trySubscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:41:25)",
            "    at /node_modules/rxjs/dist/cjs/internal/Observable.js:35:31",
            "    at Object.errorContext (/node_modules/rxjs/dist/cjs/internal/util/errorContext.js:22:9)",
            "    at Observable.subscribe (/node_modules/rxjs/dist/cjs/internal/Observable.js:26:24)",
            "    at /node_modules/rxjs/dist/cjs/internal/firstValueFrom.js:24:16",
            "    at new Promise (<anonymous>)",
            "    at firstValueFrom (/node_modules/rxjs/dist/cjs/internal/firstValueFrom.js:8:12)"
          ]
        }
      }
    }
  ],
  "data": null
}

下面的命令返回,

sudo docker inspect web_server 

[
    {
        "Name": "web_server",
        "Id": "23b4a40928a88861f7a063db4dac5c491db5384181d28ee5563db52f96c22e55",
        "Created": "2022-09-06T17:55:54.611611429Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "181868f91a188056e5f21de4bb6ca16b92f36befcd832386206256701b7be16a": {
                "Name": "question-service",
                "EndpointID": "01a4c375b95be1eb9be58993abcb8bf15fe2a8d91ac2635c4a3746036fc51747",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            },
            "828c06298e42184665507f3c6bd73a54feb36e3da3214360a015ba67104f1fdd": {
                "Name": "api-gateway",
                "EndpointID": "2ca0ba9b3f6664095e8146b5d6243362fc0a5188a73c80b7afd47207a5c62e1e",
                "MacAddress": "02:42:ac:12:00:03",
                "IPv4Address": "172.18.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
docker dns nestjs grpc
3个回答
1
投票

我可以通过更改客户端和服务器配置中的 URL 来解决此问题,如下所示。

export const microserviceOptions: ClientOptions = {
  transport: Transport.GRPC,
  options: {
    package: 'questionPackage',
    protoPath: join(__dirname, '../question/question.proto'),
    url: 'dns:///question-service:40000',
  },
};

请参阅此答案了解更多信息。您也可以参考这篇博客文章


0
投票

在运行具有入口点

eventstoredb
的容器时,我遇到了
dumb-init
的错误。我也尝试了
tini
并得到了同样的错误。

这导致了错误

 ENTRYPOINT ["dumb-init", "node", "./dist/index.js"]

还有这个

ENTRYPOINT ["/sbin/tini","--", "node", "./dist/index.js"]

但这有效

ENTRYPOINT ["node", "./dist/index.js"]


0
投票

我在将结构版本从旧版本更新到最新版本时遇到此错误。这里的问题是链代码没有在所需的 docker 网络中启动。因此,根据 docker 网络的名称将其添加到 env 文件中。

CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fabric_test //Replace with your docker network name
© www.soinside.com 2019 - 2024. All rights reserved.