Как приложение NestJS может прослушивать тот же порт, что и подключенный микросервис?

#node.js #nestjs

#node.js #nestjs

Вопрос:

Я пытаюсь понять, как работают микросервисы Nest.

Давайте начнем с этого примера из документации (https://docs.nestjs.com/faq/hybrid-application )

 const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});
// microservice #2
const microserviceRedis = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.REDIS,
  options: {
    url: 'redis://localhost:6379',
  },
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
 

После прохождения источника (https://github.com/nestjs/nest ), я понимаю connectMicroservice , создает a net.Server при использовании TCP , и сервер начинает прослушивать при startAllMicroservicesAsync вызове.
Но затем app.listen следует инициализировать прослушивание базового веб-сервера Nest.

Почему это не вызывает ошибку?

Я проверил, что произойдет, если у меня есть два микросервиса, подключенных к порту. Это, конечно, выдает ошибку. Чего мне здесь не хватает?

 // CODE CAUSES ERROR AS EXPECTED

const app = await NestFactory.create(AppModule);
// microservice #1
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});

// microservice #2  <--- THIS WILL CAUSE AN ERROR AS EXPECTED
const microserviceTcp = app.connectMicroservice<MicroserviceOptions>({
  transport: Transport.TCP,
  options: {
    port: 3001,
  },
});

await app.startAllMicroservicesAsync();
await app.listen(3001);
 

Ответ №1:

На случай, если кому-то интересно: это потому, что микросервисы и «классические» приложения Nest регистрируют порты с разными значениями по умолчанию. Используя lsof для проверки открытых TCP-сокетов, это сразу понятно.

 localhost:3000 (LISTEN). // microservice
*:3000 (LISTEN)          // http app
 

Если я явно укажу hostname as localhost для app.listen in main.ts , HTTP-приложение не запускается, как и ожидалось.