Микросервисная архитектура: насколько микро? и почему не возникает проблем с долгим ожиданием?
================================================================================================

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

  

По хочу изучения начал также изучать разные кейсы, и когда слышу, что у некоторых сотни, или даже тысячи микросервисов, у меня начали шевелиться волосы.  

  

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

  

При разработке приложений на ооп, я на интуитивном уровне пониманию, как нужно разделять ответственность в классах.   

  

Но, как это делать в микросервисах - не понимаю.  

  

**Проблема 1:**  

  

Например: мне необходимо из моей монолитной системы отделить каталог, и раздробить на микросервисы.  

  

Для каталога, я могу представить себе только 3 микросервиса:  

1. Структура каталога.  

2. Информация по товарам (описания, картинки, характеристики).  

3. Информация по офферам (остатки, цены).  

  

Подскажите пожалуйста, правильно ли я себе это представил ? (т.к. при изучении кейсов, вижу, что у некоторых получается десяток микросервисов) если нет, то в чем проблема, и что я не понимаю ? понятное дело, что у всех бывает по разному, и все зависит от задач.  

  

**Проблема 2:**  

  

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

  

Вопрос: почему это не тормозит ? ведь получение данных в классических микросервисах, это rest-запросы.   

  

**Проблема 3:**  

  

При разделении одной сущности на множество микросервисов, как решаются проблемы с консистентностью данных ? Транзакционность (это на уровне приложения решается ?) ?  

  

Очень буду благодарен, если кто-то разъяснит, чтобы у меня было понимание такой архитектуры.   

И также буду благодарен за ссылки на кейсы/учебные материалы по теме. 

 Вы задаётесь очень сложными вопросами, развёрнутый ответ на каждый из которых вряд ли влезет в лимит символов ресурса. Чтобы разобраться с первой проблемой, стоит прочитать "[Предметно-ориентированное проектирование](https://www.ozon.ru/product/predmetno-orientirovannoe-proektirovanie-ddd-strukturizatsiya-slozhnyh-programmnyh-sistem-147107976/?sh=NWL__ciR)" Эванса. Грубо говоря, микросервис должен оперировать [небольшим самостоятельным подмножеством данных](https://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%B4%D0%BC%D0%B5%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5#%D0%9E%D0%B3%D1%80%D0%B0%D0%BD%D0%B8%D1%87%D0%B5%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82). Для поиска ответов на вторую и третью проблему хорошим стартом может быть "[Высоконагруженные приложения](https://www.ozon.ru/product/vysokonagruzhennye-prilozheniya-programmirovanie-masshtabirovanie-podderzhka-kleppman-martin-211433195/?sh=l3MlvvT1)" Клепмана. Да, взаимодействие внутри микросервисной системы очевидно медленнее, чем вызовы внутри монолита, у всего есть цена. Но при правильно написанном коде, правильно выбранной архитектуре и правильно построенной инфраструктуре скорость всё ещё достаточно, чтобы отвечать на запросы за доли секунды. А для согласованности приходится применять подходы вроде паттерна "сага". 

 1. ИМХО, 90% зависит от задач и от организации. То есть есть смысл в сотнях сервисах для громадной фирмы, но мне трудно представить чтобы это имело смысл для группы из трех разработчиков  

2. Как уже сказали, если не тормозит то потому что сервисы очень близко друг к другу. Но скорость - не единственная проблема. Мониторинг, дебаггинг - все выглядит совсем не так как раньше.  

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

  

Disclaimer - я DevOps, не архитект.  

  

См.   

[https://world.hey.com/joaoqalves/disasters-i-ve-se...](https://world.hey.com/joaoqalves/disasters-i-ve-seen-in-a-microservices-world-a9137a51)   

[https://medium.com/microservices-in-practice/micro...](https://medium.com/microservices-in-practice/microservices-in-practice-7a3e85b6624c)  

<https://k8s.af/> - Kubernetes Failure Stories  

[highscalability.com/blog/category/example](http://highscalability.com/blog/category/example) - Real Life Architectures 

> для расписала нашего монолита из-за проблем с масштабируемостью

  

Не очень понял связь между монолитом и масштабируемостью. Если следовать [вот этим правилам](https://12factor.net/ru/), то любой монолит будет отлично масштабироваться. Я бы на вашем месте проект привёл именно к соответствию этим правилам, а не спешил перелезть на микросервисы, т.к. и у них проблем хватает.  

> Проблема 1:

  

Почему только 3? У вашего магазина нет авторизации? Есть - это отдельный микросервис. Рассылка элетронной почты есть? Есть - ещё один микросервис. Смски шлёте? Ещё один. Другое дело, что писать это всё, понятное, дело должен не один человек, и, скорее всего, не всё на php.  

> Проблема 2:

  

Последовательно (синхронно) в кучу сервисов никто запросы не делает. В Guzzle (библиотека для http-запросов) есть асинхронный режим, кстати. То есть можно сразу сделать обращение к нескольким сервисам и собрать результаты (время будет равно времени выполнения самого медленного запроса). Но вы и с фронтенда можете сделать обращение к нескольким сервисам сразу асинхронно ведь. Если вопрос в авторизации, то для этого можно использовать jwt-токены - их каждый сервис может сам валидировать. Также можно кешировать данные в определённых ситуациях и даже дублировать в разных сервисах (в микросервисной архитектуре это допустимо).  

> Проблема 3:

  

Обычно никак не решается, как ни странно. Распределённые транзакции - это боль. А общую базу для нескольких микросервисов использовать нельзя - это антипаттерн.  

  

P.s. возможно, в вашем случае не нужно всё дробить на кучи микросервисов. Это долго, дорого, трудоёмко - и сложно сделать так, чтобы было удобно, особенно когда опыта нет. Попробуйте что-то одно отделить по мере надобности, потом другое. А дробить бездумно точно никакого смысла не имеет. 

 обычно микросервисы нарезают так чтоб они обслуживали отдельную "тематику", которую можно было бы отдельно маштабировать и отдельно дорабатывать, от всех остальных. Пример:  

микросервис который обрабатывает работу каталога (и всё что связанно с ним), отдельно микросервис который будет работать с доставкой и отправкой заказов, микросервис который работает с партнёрской программой и начислением балов лояльности, и микросервис который занимается обработкой платежей. У каждого из этих микросервисов желательно иметь свою БД, тогда они могут независимо друг от друга работать и независимо маштабироваться, только отвечая потребностям свой нагрузки - очевидно нагрузка на каталог сильно выше чем на сервис обработки платежей (например каталог может обрабатывать 10 узлов, заказы обрабатывают 3 узла а платежи 1 узел)  

При использовании монолита вы масштабируете сразу все сервисы на узлы, что не так эффективно.   

-------  

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

-------  

транзакционность обычно осуществляется через SAGA паттерн.  

По поводу консистентности - если ты начинаешь масштабировать систему, значит состояние размазывается по множеству разных узлов/сервисов, вся суть что эти узлы/сервисы могут независимо друг от друга работать, значит консистентность будем мешать независимой работе (тоесть производительности), если сервисы зависимы то они не маштабируются (раз один узел ожидает что-то для работы от другого узла), поэтому там предъявляются "ослабленные требования" к консистентности состояния, как правило используют eventual consistency (согласованность в конечном счете), говорят что рано или поздно типа состояние в системе будет согласованно, если не будут поступать новые данные)  

ну а пока данные поступают, то состояние может быть не согласованно между узлами. 

 Грамотно написанный монолит не имеет проблем с масштабируемостью. Сильно сомневаюсь что у вас там объёмы Гугла. С другой стороны, для карьеры, для резюме, для практики, конечно лучше раздербанить монолит у своего текущего работодателя, за его же деньги. Поэтому сильно не заморачивайтесь что да как. Серьёзно, без иронии. Жизнь такая, не мы такие. 

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

  

Добро пожаловать в дивный мир микросервисов. Теперь у тебя будут не только проблемы с масштабируемостью, но и куча других.  

  

> ...SRP, т.е. каждый микросервис, должен отвечать только за одну задачу.

  

Это не так, SRP говорит о другом.  

  

Все остальные проблемы — это большие вопросы, которые нужно разбирать долго.   

И прочитай [здесь](https://qna.habr.com/q/1042370#answer_2013802). Если коротко: микросервисы — это инфраструктура. Будешь думать, что они решат твои бизнесовые проблемы — получишь ещё больше бизнесовых проблем и целую гору инфраструктурных. А масштабировать можно и монолит прекрасно. 

 Если единственная проблема, это масштабирование по производительности, до попробуйте решить ее железом и минимальным разделением приложения. Переписывать монолит на микросервисы, это всегда дороже, ОЧЕНЬ СИЛЬНО дороже. 

 Привет, если интересуют реализация Микросервисной архитектуры на .NET 6, то [вот здесь](https://youtube.com/playlist?list=PLePGPxR0FDm-wuNOldx0o_GkgY_MVrGCb), пример внедрения микросервисов для интернет магазина. Может быть это поможет, на практическом примере понять, как это работает, и какие дополнительные проблемы там возникают. 

 Как же это не тормозит, на любой современный крупный ресурс зайдите, любой кабинет любого банка или мобильного оператора грузится несколько минут (те самые заглушки во всех местах, на месте которых должны быть какие-либо данные), постоянно в плеймаркете юзеры пишут мол что там может так долго грузиться, а все уже, переписали в свое время на микросервисы, ибо модно-молодежно, не переписывать же обратно.