Microservice Architecture Design in a NodeJS/NestJS Environment | Online Retail System
Проектирование микросервисной архитектуры в среде NodeJS/NestJS
Сценарий: Перед вами стоит задача разработать микросервисную архитектуру для системы онлайн-ритейла. Эта система должна управлять различными сервисами, такими как каталог товаров, учетные записи пользователей, заказы и обработка платежей.
Подразделение микросервисов:
-
Product Catalog Service (Служба «Управление товарами»)
База данных: MongoDB или аналогичная база данных NoSQL для гибкой схемы и быстрого поиска информации о продукте;
-
Доступный функционал:
Управление продуктами;
Управление категориями продуктов;
Управление складом (Складскими запасами).
-
User Account Service (Служба учетных записей пользователей)
База данных: Реляционная база данных PostgreSQL или MySQL для хранения таких данных, как профили пользователей, аутентификация и авторизация;
Доступный функционал: Работа с учетными записями пользователей, аутентификацией, авторизацией и данными, связанными с пользователями.
-
Order Service (Служба «Управление заказами»)
База данных: MongoDB или база данных SQL, в зависимости от сложности данных, связанных с заказами и необходимости обеспечения транзакционной целостности;
Доступный функционал: Управление заказами, создание, обновление и отслеживание статуса заказов.
-
Payment Processing Service (Служба «Обработка платежей»)
База данных: Может не требовать базы данных, если в основном занимается интеграцией платежных шлюзов. Однако он может хранить журналы транзакций в надежном хранилище, например Elasticsearch;
Доступный функционал: Интегрируется с платежными шлюзами, обрабатывает транзакции, регистрирует информацию о платежах.
Связь между микросервисами
RESTful API или GraphQL: Каждый микросервис предоставляет API для взаимодействия. NestJS предоставляет отличные инструменты для создания RESTful API или конечных точек GraphQL, обеспечивая стандартизированное взаимодействие;
Брокер сообщений (опционально): Реализуйте брокер сообщений, например RabbitMQ или Kafka, для асинхронного взаимодействия между сервисами. Это обеспечит свободное взаимодействие и лучшую масштабируемость.
Обеспечение согласованности данных
Синхронная связь: Для критических операций, требующих немедленной согласованности (например, размещение заказа), используйте синхронную связь. Микросервисы могут напрямую взаимодействовать через REST или GraphQL для поддержания согласованности данных;
Конечная согласованность: Для некритичных операций (например, обновление данных профиля пользователя) асинхронная связь с брокером сообщений позволяет поддерживать конечную согласованность без блокировки сервисов.
Обработка транзакций
Распределенные транзакции: Используйте двухфазный протокол фиксации или шаблон (паттерн) SAGA для распределенных транзакций, охватывающих несколько микросервисов. Реализуйте компенсирующие транзакции для обработки частичных сбоев и обеспечения согласованности данных между сервисами;
Журнал транзакций/сортировка событий: Ведите журналы транзакций или используйте поиск событий для отслеживания изменений в микросервисах. Это поможет восстановить состояния и устранить несоответствия.
Безопасность
JWT‑токены: Внедрите JWT (JSON Web Tokens) для аутентификации и авторизации между сервисами. NestJS предоставляет надежные механизмы аутентификации;
HTTPS: Обеспечьте безопасное взаимодействие между микросервисами с помощью HTTPS, чтобы предотвратить утечку данных.
Надежность системы
Мониторинг и ведение логов: Внедрите системы логирования и мониторинга (например, стек ELK, Prometheus, Grafana) для отслеживания состояния, производительности и ошибок системы;
Контейнеризация и оркестровка: Используйте Docker для контейнеризации и Kubernetes для оркестровки, чтобы обеспечить масштабируемость, отказоустойчивость и простоту развертывания.
Заключение
В целом, эта архитектура разделяет функционал между службами управления, которые используют соответствующие базы данных в зависимости от потребностей в данных, использует коммуникационные стратегии для обеспечения согласованности, обрабатывает транзакции в распределенных средах, уделяет приоритетное внимание безопасности и обеспечивает надежность системы с помощью мониторинга и контейнеризации.
Изучаю архитектуру веб‑приложений, таких как «Система электронной коммерции».
Данная статья показалась мне интересной и я решил сохранить ее перевод.
В первую очередь для себя, ну и еще, чтобы почитать ваши комментарии)Буду рад вашим комментариям, предложениям и замечаниям) Спасибо.
Комментарии (9)
Goodzonchik
05.09.2024 21:29+2А при чем тут nodejs и nestjs? В тексте они упоминаются один раз. Как будто их можно заменить на любой сервис написанный на "язык + фреймворк выберите сами".
Также кажется указывать конкретные технологии при проектировании не очень хорошая идея. Ну или надо уточнять почему нам больше подходит MongoDb для поиска, потому что в зависимости от функционала, архитектурных решений можно вести эффективный поиск в реляционной базе или, вовсе, в графовой.
sergey_prokofiev
05.09.2024 21:29Как то ниочем. Побили проект на предметные области. Ну ок.
Безопасность: зачем https внутри защищенной среды? Зачем взаимная аутентификация сервисов? Ничего не сказано ни о шифровании данных на дисках, о хранении/ротации сертификатов. Не, может оно так и над ов вашем случае, но почему так?
Выбор баз - почему именно такой, какие ожидаются обьемы данных?
Причем тут вообще node/nest?
И еще миллион открытых вопросов.
leninD
05.09.2024 21:29К статье очень много вопросов, если мы и так тащим в проект PG/MySql то зачем нам mongodb? Решать проблемы с схемой? Между сервисами не используем grpc или другой протокол с поддержкой схемы потому что выбрали js/ts? И тд и тп
tuxi
Если микросервисы внутри защищенного периметра, зачем их загонять в https для связи между собой?
lear
Тот же вопрос и про jwt.
Как по мне, jwt самая переоцененная вещь. Если мы хотим меньше делать запросов к бд, то возникают проблемы с принудительной инвалидацией токенов. Или как в данном случае общение происходит в доверенной сети и непонятно для чего jwt в принципе пихать...
Вот даже откопал:
https://habr.com/ru/articles/502702/comments/#comment_21636220
Animila
Согласен. Когда я работал в старой компании, там авторизация была на jwt токенах. Мне дали задачу реализовать отслеживание сессий и возможность отключить их. Сначала думал сделать на редисе список токенов, которые отозвали, и спрашивать постоянно их. А потом понял, что это все какая-то херня. В итоге полностью всю авторизацию переписал на cookie + session + seans. Хотя у меня до сих пор кит вопрос по поводу масштабирования такой системы. В плане, я теперь ограничен одним сервером, или как?
P.S. самый прикол в том, что когда я спрашивал старых сотрудников, а зачем вам jwt, мне все дружно отвечали "ну хз, микросервисы же вроде"
olku
Сначала был HTTP без состояния. Потом в заголовках стали передавать указатель на состояние - куки. Для монолита достаточно, но в распределенных архитектурах резольвинг указателя на состояние стал проблемой. Ее решали двумя способами - общим для всех сервисов хранилищем сессий, или шифрованием сессии и передаче ее в заголовках во всех запросах. Второй вариант каноничен для микросервисной архитектуры и отлично масштабируем, но выбор за архитектором.
leon0399
Да потому что токен должен быть короткоживущим. ТТЛ токена - 2 минуты, потом на рефреш. Тогда и не будет проблем. А по-хорошему вообще засунуть все сервисы за гейтвей - он будет проверять токен перед всеми сервисами, блокировать запрос если токен в блеклисте, и обновлять его если срок жизни подходит к концу, и возвращать его в респонзе сервера в хедере
Прежде чем жаловаться что «технология X» такая ужасная, убедитесь что вы правильно ею пользуетесь
olku
Незачем. А для безопасности, если приспичило в zero trust, нужен mtls - меш или сайдкар прокси.
Брокер сообщений обязателен для микросервисной архитектуры. Большинство событий имеют асинхронную природу.
Ничего не сказано про API Gateway и безопасность кластера.
Не раскрыто Observability. Сейчас переходят на OpenTelemetry.
Есть более чем два протокола для коммуникации. Из текстовых, по моему, незаслуженно обходят Json-RPC, который лучше подходит для межсервисных связей чем REST.