如何修复"14 UNAVAILABLE: Name resolution failed for target dns:http://sample-service:40000" GRPC + 码头工人错



我在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}}

客户端的env

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}}

服务器的env

IMAGE_NAME=question-service

服务器(问题服务(的主.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();

客户端集成是这样的,grp.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',
},
};

questions.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网关的graphql-epoint来获取所有问题时,它返回以下错误,

{
"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": {}
}
]

我能够通过如下更改客户端和服务器配置中的URL来解决这个问题。

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

有关更多信息,请参阅本文。你也可以参考这个博客文章

在运行具有入口点dumb-init的容器时,eventstoredb出现此错误。我也尝试了tini,结果也出现了同样的错误。

这导致错误

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

这也是

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

但这是

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