Microservice Architecture Design in a NodeJS/NestJS Environment | Online Retail System


Проектирование микросервисной архитектуры в среде NodeJS/NestJS

Сценарий: Перед вами стоит задача разработать микросервисную архитектуру для системы онлайн-ритейла. Эта система должна управлять различными сервисами, такими как каталог товаров, учетные записи пользователей, заказы и обработка платежей.

Подразделение микросервисов:

  1. Product Catalog Service (Служба «Управление товарами»)

    • База данных: MongoDB или аналогичная база данных NoSQL для гибкой схемы и быстрого поиска информации о продукте;

    • Доступный функционал:

      • Управление продуктами;

      • Управление категориями продуктов;

      • Управление складом (Складскими запасами).

  2. User Account Service (Служба учетных записей пользователей)

    • База данных: Реляционная база данных PostgreSQL или MySQL для хранения таких данных, как профили пользователей, аутентификация и авторизация;

    • Доступный функционал: Работа с учетными записями пользователей, аутентификацией, авторизацией и данными, связанными с пользователями.

  3. Order Service (Служба «Управление заказами»)

    • База данных: MongoDB или база данных SQL, в зависимости от сложности данных, связанных с заказами и необходимости обеспечения транзакционной целостности;

    • Доступный функционал: Управление заказами, создание, обновление и отслеживание статуса заказов.

  4. Payment Processing Service (Служба «Обработка платежей»)

    • База данных: Может не требовать базы данных, если в основном занимается интеграцией платежных шлюзов. Однако он может хранить журналы транзакций в надежном хранилище, например Elasticsearch;

    • Доступный функционал: Интегрируется с платежными шлюзами, обрабатывает транзакции, регистрирует информацию о платежах.

Связь между микросервисами

  1. RESTful API или GraphQL: Каждый микросервис предоставляет API для взаимодействия. NestJS предоставляет отличные инструменты для создания RESTful API или конечных точек GraphQL, обеспечивая стандартизированное взаимодействие;

  2. Брокер сообщений (опционально): Реализуйте брокер сообщений, например RabbitMQ или Kafka, для асинхронного взаимодействия между сервисами. Это обеспечит свободное взаимодействие и лучшую масштабируемость.

Обеспечение согласованности данных

  1. Синхронная связь: Для критических операций, требующих немедленной согласованности (например, размещение заказа), используйте синхронную связь. Микросервисы могут напрямую взаимодействовать через REST или GraphQL для поддержания согласованности данных;

  2. Конечная согласованность: Для некритичных операций (например, обновление данных профиля пользователя) асинхронная связь с брокером сообщений позволяет поддерживать конечную согласованность без блокировки сервисов.

Обработка транзакций

  1. Распределенные транзакции: Используйте двухфазный протокол фиксации или шаблон (паттерн) SAGA для распределенных транзакций, охватывающих несколько микросервисов. Реализуйте компенсирующие транзакции для обработки частичных сбоев и обеспечения согласованности данных между сервисами;

  2. Журнал транзакций/сортировка событий: Ведите журналы транзакций или используйте поиск событий для отслеживания изменений в микросервисах. Это поможет восстановить состояния и устранить несоответствия.

Безопасность

  1. JWT‑токены: Внедрите JWT (JSON Web Tokens) для аутентификации и авторизации между сервисами. NestJS предоставляет надежные механизмы аутентификации;

  2. HTTPS: Обеспечьте безопасное взаимодействие между микросервисами с помощью HTTPS, чтобы предотвратить утечку данных.

Надежность системы

  1. Мониторинг и ведение логов: Внедрите системы логирования и мониторинга (например, стек ELK, Prometheus, Grafana) для отслеживания состояния, производительности и ошибок системы;

  2. Контейнеризация и оркестровка: Используйте Docker для контейнеризации и Kubernetes для оркестровки, чтобы обеспечить масштабируемость, отказоустойчивость и простоту развертывания.

Заключение

В целом, эта архитектура разделяет функционал между службами управления, которые используют соответствующие базы данных в зависимости от потребностей в данных, использует коммуникационные стратегии для обеспечения согласованности, обрабатывает транзакции в распределенных средах, уделяет приоритетное внимание безопасности и обеспечивает надежность системы с помощью мониторинга и контейнеризации.


Изучаю архитектуру веб‑приложений, таких как «Система электронной коммерции».
Данная статья показалась мне интересной и я решил сохранить ее перевод.
В первую очередь для себя, ну и еще, чтобы почитать ваши комментарии)

Буду рад вашим комментариям, предложениям и замечаниям) Спасибо.

Комментарии (9)


  1. tuxi
    05.09.2024 21:29

    Если микросервисы внутри защищенного периметра, зачем их загонять в https для связи между собой?


    1. lear
      05.09.2024 21:29

      Тот же вопрос и про jwt.
      Как по мне, jwt самая переоцененная вещь. Если мы хотим меньше делать запросов к бд, то возникают проблемы с принудительной инвалидацией токенов. Или как в данном случае общение происходит в доверенной сети и непонятно для чего jwt в принципе пихать...

      Вот даже откопал:
      https://habr.com/ru/articles/502702/comments/#comment_21636220


      1. Animila
        05.09.2024 21:29

        Согласен. Когда я работал в старой компании, там авторизация была на jwt токенах. Мне дали задачу реализовать отслеживание сессий и возможность отключить их. Сначала думал сделать на редисе список токенов, которые отозвали, и спрашивать постоянно их. А потом понял, что это все какая-то херня. В итоге полностью всю авторизацию переписал на cookie + session + seans. Хотя у меня до сих пор кит вопрос по поводу масштабирования такой системы. В плане, я теперь ограничен одним сервером, или как?

        P.S. самый прикол в том, что когда я спрашивал старых сотрудников, а зачем вам jwt, мне все дружно отвечали "ну хз, микросервисы же вроде"


      1. olku
        05.09.2024 21:29

        Сначала был HTTP без состояния. Потом в заголовках стали передавать указатель на состояние - куки. Для монолита достаточно, но в распределенных архитектурах резольвинг указателя на состояние стал проблемой. Ее решали двумя способами - общим для всех сервисов хранилищем сессий, или шифрованием сессии и передаче ее в заголовках во всех запросах. Второй вариант каноничен для микросервисной архитектуры и отлично масштабируем, но выбор за архитектором.


      1. leon0399
        05.09.2024 21:29

        Да потому что токен должен быть короткоживущим. ТТЛ токена - 2 минуты, потом на рефреш. Тогда и не будет проблем. А по-хорошему вообще засунуть все сервисы за гейтвей - он будет проверять токен перед всеми сервисами, блокировать запрос если токен в блеклисте, и обновлять его если срок жизни подходит к концу, и возвращать его в респонзе сервера в хедере

        Прежде чем жаловаться что «технология X» такая ужасная, убедитесь что вы правильно ею пользуетесь


    1. olku
      05.09.2024 21:29
      +1

      Незачем. А для безопасности, если приспичило в zero trust, нужен mtls - меш или сайдкар прокси.

      Брокер сообщений обязателен для микросервисной архитектуры. Большинство событий имеют асинхронную природу.

      Ничего не сказано про API Gateway и безопасность кластера.

      Не раскрыто Observability. Сейчас переходят на OpenTelemetry.

      Есть более чем два протокола для коммуникации. Из текстовых, по моему, незаслуженно обходят Json-RPC, который лучше подходит для межсервисных связей чем REST.


  1. Goodzonchik
    05.09.2024 21:29
    +2

    А при чем тут nodejs и nestjs? В тексте они упоминаются один раз. Как будто их можно заменить на любой сервис написанный на "язык + фреймворк выберите сами".

    Также кажется указывать конкретные технологии при проектировании не очень хорошая идея. Ну или надо уточнять почему нам больше подходит MongoDb для поиска, потому что в зависимости от функционала, архитектурных решений можно вести эффективный поиск в реляционной базе или, вовсе, в графовой.


  1. sergey_prokofiev
    05.09.2024 21:29

    Как то ниочем. Побили проект на предметные области. Ну ок.

    Безопасность: зачем https внутри защищенной среды? Зачем взаимная аутентификация сервисов? Ничего не сказано ни о шифровании данных на дисках, о хранении/ротации сертификатов. Не, может оно так и над ов вашем случае, но почему так?

    Выбор баз - почему именно такой, какие ожидаются обьемы данных?

    Причем тут вообще node/nest?

    И еще миллион открытых вопросов.


  1. leninD
    05.09.2024 21:29

    К статье очень много вопросов, если мы и так тащим в проект PG/MySql то зачем нам mongodb? Решать проблемы с схемой? Между сервисами не используем grpc или другой протокол с поддержкой схемы потому что выбрали js/ts? И тд и тп