Что такое microservices transport (TCP, Redis, Kafka) в NestJS?

SeniorNestJS · Backend·Обновлено 2 сентября 2026
Коротко
Transport в NestJS microservices — это транспортный слой, через который сервисы обмениваются сообщениями (TCP, Redis, Kafka, NATS, gRPC, RabbitMQ, MQTT); NestJS абстрагирует его через единый интерфейс ClientProxy и декораторы @MessagePattern/@EventPattern, а конкретную реализацию транспорта подключает через стратегию в createMicroservice.

Транспортный слой в NestJS microservices

NestJS не является брокером сообщений сам по себе — он предоставляет унифицированную абстракцию поверх разных транспортов. При создании микросервиса через NestFactory.createMicroservice() вы указываете Transport — стратегию, которая определяет протокол доставки сообщений. Приложение работает с одинаковыми декораторами @MessagePattern и @EventPattern независимо от того, какой транспорт выбран.

TCP

Встроенный транспорт по умолчанию, ничего дополнительно ставить не нужно. Работает по схеме точка-точка: клиент открывает сокет к конкретному хосту/порту сервиса. Подходит для простых внутренних RPC-вызовов, но не даёт балансировки из коробки и требует service discovery на уровне инфраструктуры (например, Kubernetes Service).

Redis

Использует pub/sub Redis как шину сообщений. Требует пакет ioredis. Хорошо подходит для fire-and-forget событий и лёгких нагрузок, но pub/sub Redis не гарантирует доставку — если подписчик офлайн, сообщение теряется, персистентности очереди нет (в отличие от Redis Streams, которые NestJS напрямую как транспорт не использует).

Kafka

Использует kafkajs под капотом. Kafka — это распределённый лог событий с партициями, consumer group'ами и гарантией порядка внутри партиции. Подходит для event-driven архитектур, где важны durability, replay событий и горизонтальное масштабирование consumer'ов. Требует настройки client (brokers) и consumer (groupId).

Паттерны обмена сообщениями

  • @MessagePattern — request-response: клиент ждёт ответ (client.send()), под капотом это Observable.
  • @EventPattern — fire-and-forget события (client.emit()), ответа не ожидается, используется для событийной интеграции.

ClientProxy

Отправка сообщений из другого сервиса или из HTTP-контроллера идёт через ClientProxy, который регистрируется через ClientsModule.register() с тем же transport-объектом, что и на стороне получателя.

Гибридные приложения

Через app.connectMicroservice() можно поднять и HTTP, и один или несколько микросервисных транспортов в одном процессе — это удобно, когда сервис одновременно принимает REST-запросы и слушает события Kafka.

Кастомная сериализация

Для каждого транспорта можно задать свои serializer/deserializer в опциях стратегии — это важно для Kafka, где часто нужен Avro/Protobuf вместо JSON по умолчанию.

Ключевое отличие для собеседования

TCP — простой синхронный RPC без гарантий доставки при сбоях сети. Redis pub/sub — быстрый, но без персистентности и at-least-once доставки. Kafka — надёжный event log с партиционированием, consumer group'ами, возможностью replay и масштабирования, но с более высокой операционной сложностью и задержкой по сравнению с TCP.

Что хочет услышать интервьюер

Понимание, что transport — это стратегия (Transport enum), а не сам брокер, и NestJS абстрагирует протокол через единый API

Чёткое разграничение @MessagePattern (request-response) и @EventPattern (fire-and-forget)

Знание отличий гарантий доставки: TCP — point-to-point без retry, Redis pub/sub — at-most-once, Kafka — durable log с consumer group и replay

Понимание роли ClientProxy и того, что конфигурация транспорта должна совпадать у отправителя и получателя

Осведомлённость про гибридные приложения (HTTP + микросервисный транспорт в одном процессе)

Пример: Микросервис на TCP

// main.ts
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.TCP,
      options: { host: '0.0.0.0', port: 3001 },
    },
  );
  await app.listen();
}
bootstrap();

Пример: Микросервис на Kafka с consumer group

// main.ts
import { NestFactory } from '@nestjs/core';
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    AppModule,
    {
      transport: Transport.KAFKA,
      options: {
        client: { brokers: ['localhost:9092'] },
        consumer: { groupId: 'orders-consumer' },
      },
    },
  );
  await app.listen();
}
bootstrap();

Пример: Обработчики сообщений и событий

import { Controller } from '@nestjs/common';
import { MessagePattern, EventPattern, Payload } from '@nestjs/microservices';

@Controller()
export class OrdersController {
  // request-response: клиент ждёт результат
  @MessagePattern('orders.get')
  getOrder(@Payload() id: string) {
    return { id, status: 'shipped' };
  }

  // fire-and-forget: ответ не отправляется
  @EventPattern('orders.created')
  handleOrderCreated(@Payload() data: { orderId: string }) {
    // например, отправка уведомления
    console.log('Новый заказ создан:', data.orderId);
  }
}

Пример: Клиент через ClientsModule

import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';

@Module({
  imports: [
    ClientsModule.register([
      {
        name: 'ORDERS_SERVICE',
        transport: Transport.REDIS,
        options: { host: 'localhost', port: 6379 },
      },
    ]),
  ],
})
export class AppModule {}

Типичные ошибки

Путают @MessagePattern и @EventPattern, считая что оба всегда ждут ответ

Не знают, что Redis pub/sub в NestJS не гарантирует доставку сообщений при недоступности подписчика

Считают Kafka взаимозаменяемым с очередью типа RabbitMQ, не упоминая партиции и consumer group как ключевые отличия

Забывают, что клиент и сервер должны использовать идентичную конфигурацию транспорта (host/port, brokers, groupId)

Не упоминают, что TCP-транспорт не даёт балансировки нагрузки и service discovery из коробки

Лучшие курсы по теме

изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Node.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее