Учебный проект, демонстрирующий взаимодействие двух NestJS-сервисов через Apache Kafka.
┌────────────┐ ┌─────────┐ ┌────────────┐
│ Producer │──emit──▸│ Kafka │──push──▸│ Consumer │
│ (HTTP app) │ │ (broker)│ │(microservice)│
└────────────┘ └─────────┘ └────────────┘
Producer — обычное NestJS HTTP-приложение (порт 3001). Каждую секунду отправляет событие user.created в Kafka.
Kafka — брокер сообщений. Принимает сообщения от продюсера, хранит их в топиках и доставляет консюмерам.
Consumer — NestJS-микросервис (без HTTP). Подписан на топик user.created и выводит полученные события в консоль.
- Producer создает объект события
UserCreatedEventи вызываетclient.emit('user.created', event) - Библиотека
@nestjs/microservicesсериализует событие и отправляет его в Kafka-топикuser.created - Kafka сохраняет сообщение в партицию топика и присваивает ему offset
- Consumer состоит в consumer group
user-consumer-groupи подписан на топик через@EventPattern('user.created') - Kafka доставляет сообщение консюмеру, NestJS десериализует его и вызывает метод
handleUserCreated
Shared-пакет @app/contracts, используемый и продюсером, и консюмером.
| Файл | Что делает |
|---|---|
src/base.event.ts |
Базовый интерфейс BaseEvent<T> — общая структура для всех событий |
src/user/user-created.event.ts |
Тип UserCreatedEvent — конкретное событие создания пользователя |
src/user/user.events.ts |
Константа USER_CREATED_EVENT = 'user.created' — имя топика |
| Файл | Что делает |
|---|---|
src/main.ts |
Запуск обычного HTTP-приложения на порту 3001 |
src/kafka/kafka.module.ts |
Регистрация Kafka-клиента через ClientsModule с указанием брокера |
src/kafka/kafka.service.ts |
Сервис-обертка: подключается к Kafka в onModuleInit, метод emit() отправляет сообщения |
src/app.service.ts |
Бизнес-логика: каждую секунду (@Interval) формирует событие и отправляет в Kafka |
| Файл | Что делает |
|---|---|
src/main.ts |
Запуск как микросервис через NestFactory.createMicroservice с транспортом Transport.KAFKA |
src/app.controller.ts |
@EventPattern('user.created') — обработчик входящих событий, выводит данные в консоль |
Поднимает Kafka (KRaft, без Zookeeper) и Kafka UI для визуального просмотра топиков.
# 1. Поднять Kafka
docker compose up -d
# 2. Установить зависимости
npm install
# 3. Собрать контракты
npm run build:contracts
# 4. Запустить консюмер (в отдельном терминале)
cd consumer && npm run start:dev
# 5. Запустить продюсер (в отдельном терминале)
cd producer && npm run start:devKafka UI доступен на http://localhost:8080 — там можно увидеть топики и сообщения.
- Топик — именованный канал сообщений (
user.created). Продюсер пишет в топик, консюмер читает из него. - Consumer Group — группа консюмеров с одним
groupId. Kafka гарантирует, что каждое сообщение получит только один консюмер из группы. - Offset — порядковый номер сообщения в партиции. Консюмер запоминает offset, чтобы не обрабатывать сообщения повторно.
- EventPattern — декоратор NestJS, подписывающий метод контроллера на события из определенного топика.
- ClientKafka.emit() — fire-and-forget отправка. Не ждет ответа от консюмера (в отличие от
send()).