Comments 29
Например, мы можем определить набор функций “HR инструменты” и, при необходимости масштабирования, развернуть не второй инстанс монолита, а отдельную группу функций
Извините, а можно в общих чертах, как это просиходит?
Ну допустим резкий всплеск популярности, большой поток новых пользователей и мне нужно модуль users развернуть. Смутно понимаю, как будет только users развёрнута.
Честно, более красивым решением было бы вытащить нагруженный модуль в микросервис и масштабировать по общим принятым стандартам. Но если говорить о паттерне SUFA, то мы можем описать в сервисе все зависимости модуля и инициализировать при выкладке только их. Например, в ci/cd можно указать роль "users", зарегистрировать в DI контейнере только конкретные модули, сообщить в service-discovery свою роль и балансировать урлы с префиксом модуля только на монолиты с соответствующей ролью. Однако я настоятельно рекомендую так не делать :)
Как по мне статья не очень информативна
Как по мне основная проблема кучи микросервисов с разбросом технологий не в том что лежат не в одном проекте, а в том что есть тот самый зоопарк. 5 проектов и 5 различных коннекторов к брокеру, 3 типа библиотек под базу, ещё 10 различных вариантов деплоя. А ещё 5 различных оберток для стартапа
И куда интереснее было бы послушать про процесс причесывание всего к единому виду, и как выжить в процессе. А сложить все в один проект и выдать всем метод "запусти себя как микросевис в монолите" это не проблема
мне кажется, вы путаете понятия модульного монолита и монорепа. В моем случае модульного монолита я имею один общий деплой, один общий хост с di контейнером и общий модуль Common, где хранится единое подключение к базе, брокеру сообщений и прочему, т.е. все сервисы причесаны к единому стандарту. Это не "микросервис в монолите", это монолит с одной точкой входа, куски которого притворяются микросервисами
И куда интереснее было бы послушать про процесс причесывание всего к единому виду, и как выжить в процессе.
проблема в том, что я не знаю как выжить в процессе) по-моему единственный вариант - это делегировать задачу на другого человека, чтобы помер не ты. Это путь из боли и страданий
Ну так у вас и получилась не статья а фиг знает что. Это ж тот самый гайд как нарисовать сову. Нарисуйте круг, в затем сову)))
А проблемы с микросервисами это не проблемы микросервисов как таковых, а проблем тех кто их готовит)
Ну а про то что у вас не монорепа а один проект я понял, только без рефакторинга всех проектов это буквально создание нового приложения, и вызова метода startup(как у вас тут в дотнетах ваших) у всех приложений
Ну не прям фиг знает что, там картинки смешные есть!)
Поняла ваш посыл, я подумаю что интересного можно написать на тему рефакторинга и наведения порядков
Нормальная статья, подход понятен.
Я делал модульные монолиты, но выносить общение между модулями через внешние интеграции (http, очереди) казалось оверкилом. Кроме инфраструктурных сложностей мы ещё получаем все проблемы Eventual consistency. А в чём профит - непонятно.
Теперь вижу, в каких случаях такой подход может пригодиться.
Самое главное за проектом Common следить и всё будет хорошо.
если в рамках одного языка - единое соглашение по неймспейсам во всех микросервисах достаточно, при условии общих соглашений по конфигу. а сливать разные кодовые базы в одну - не всегда хорошее решение. а в некоторых случаях бизнеса и разделения уровней доступа - просто невозможное. и разные репозитории строгая необходимость.
имхо, адекватный набор разных кодовых баз для явно специфичных доменов предметной области со своей независимой функциональностью - штука хорошая. просто нужно уметь это готовить. плохо организованные микросервисы не есть камень в огород микросервисов. это камень в огород их организации.
если в рамках одного языка - единое соглашение по неймспейсам во всех микросервисах достаточно, при условии общих соглашений по конфигу.
не соглашусь, этого не достаточно. Как я написала в выводе, задачу через микросервисы решить можно, но придется попотеть: внедрять общие библиотеки, создавать шаблоны для выкладки, выделять отдельный микросервис для авторизации, автоматизировать обновление хостов через инструменты DevOps. Я даже изначально рассматривала этот вариант, но на мой вкус это слишком много действий для маленьких админок, возможно мы с вами в разных контекстах.
разделения уровней доступа
эту задачу я решила единой авторизацией и определением уровня доступа для каждого контроллера в модуле при помощи аттрибутов. Определяем на входе кто из сотрудников авторизовался, в какой он команде, рабочей группе и должности и решаем какие у него права на взаимодействие с модулем.
плохо организованные микросервисы не есть камень в огород микросервисов. это камень в огород их организации.
нет никаких камней в огородах, я не говорю что микросервисы это плохо. Написать хорошо можно используя любую архитектуру. У меня просто решение задачи одним способом, вы можете использовать любой другой
внедрять общие библиотеки
Это вообще желатно делать даже в монолите.
создавать шаблоны для выкладки
Какой-нибудь шаблоный докерфайл для сборки можно сделать прям из майковских инструкций минут за 30. Ещё немножко времени сгенерить каким-нибудь анзиблом по набору названий сервисов композ. У вас уже и сервис дискавери есть, поди и к апигейтвэю прикручен.
выделять отдельный микросервис для авторизации
Так вы делаете практически всё тоже самое, только отдельный хост ему не прикрутили, ведь ваши модули вещь изолированная.
обновление хостов через инструменты DevOps
docker compose pull & docker compose up -d
И дальше всё добавление новых сервисов решается добавлением в ci/cd скриптах одной строчки с названием репы( а в итоговых скриптах будет меньше строчек чем в моём комментарии). При сборке скрипты чекаутят репы по очереди, билдят контейнеры, версионируют каждый ваш сервис к примеру через gitversion(чего кстати не добиться в вашей монорепе) и перезапускают композ.
Т.е. в итоге вы изолируете модули тратя на это время(ради, как вы сами же сказали, мифической и не нужной вам возможности запустить модуль отдельно) и не получаете особо бонусов, потому что все остальные бонусы изоляции съедает монолит. Я правильно понимаю?
Вообще не очень понимаю чем это всё отличается от fsd https://learn.microsoft.com/en-us/archive/msdn-magazine/2016/september/asp-net-core-feature-slices-for-asp-net-core-mvc , кроме идеи с запуском этого всего в виде той самой asg.
Написать хорошо можно используя любую архитектуру.
Это вот вообще не всегда правда, скорее даже почти всегда не правда. Нет серебряной пули, у всех архитектур есть трейдофф, а архитектуру всегда нужно выбирать в первую очередь под задачу и требования, а во-вторую под команду( если команда не тянет микросервисы, что в целом обычная ситуация, ничего хорошего из них не выйдет).
P.S. Перечитал, звучит слегка пассивно агрессивно, а я вроде не пытался, но профиты правда не очень понятны.
Звучит так как будто вы меня упрекаете в том что я развернула монолит лишь потому что не справилась с микросервисами) Ну да ладно, мы же тут собрались просто болтать и душно проводить вечера
Да, если проделать все что вы описали, будет технически почти все то же самое что и у меня, только не в монорепе. Придет продакт, закажет "сервис, который поздравляет людей с днем рождения" и мы из шаблона создадим 16-тый сервис, который будет изолирован, масштабироваться, тащить Common библиотеку, выкладываться известным общим шаблоном ci/cd, а заодно выложим новый конфиг в апигейтвей. Еще попросим девопсов выпустить роль для нового приложения в хранилище секретов. А когда выйдет .net 10, пойдем дружно обновлять 16 сервисов. Или только 2 из них, остальные как-нибудь сами ) Кстати, иметь 16 сваггеров тоже довольно удобно. Надеюсь во всех сервисах будут использованы хотя бы одни библиотеки сериализаторов и логирования. И давайте будем честны, даже в самом идеальном мире со всеми рабочими шаблонами, создавать новую пачку API методов и новый сервис - не одно и то же. Я не против оверинжениринга, он дает мне работу. Но надо же когда-нибудь остановиться )
Написать хорошо можно используя любую архитектуру.
Из контекста имела ввиду и микросервисную, и монолитную архитектуры
Вообще не очень понимаю чем это всё отличается от fsd https://learn.microsoft.com/en-us/archive/msdn-magazine/2016/september/asp-net-core-feature-slices-for-asp-net-core-mvc , кроме идеи с запуском этого всего в виде той самой asg.
Мне не знаком этот паттерн. В исходниках, что лежат в статье, нет ничего общего с модульными монолитами https://github.com/ardalis/OrganizingAspNetCore/tree/master
Блин, а заголовок звучал как название аниме...
Самое удивительное в истории с микросервисами - это как люди много лет делали вид, что все в порядке, и вдруг к середине 20х годов прозрели, что они не гугл, а бизнесу больше неинтересно слышать в качестве причины для увеличения бюджета/сроков "особенности архитектуры". Я хорошо помню свой шок от того, как в 16 году руководство настойчиво предложило мне "поделить всё на 10" - вместо одного приложения, репозитория, ci/cd и базы сделать 10. "-Зачем?" "-Так надо!" "-Нас пятеро, нас не 50!" "-Суть не в этом, мы изолируем бизнес области" "-У нас же все разбито по модулям, все изолировано!" "-Это не то!". Мне стоило больших усилий тогда отговорить их, хотя информационный фон этому мягко говоря не способствовал. 10 years later... и эти усилия к счастью больше не нужны. Начинаешь снова верить в здравый смысл.
Начинаешь снова верить в здравый смысл.
Не спешите, AI на носу, ждем качели с vibe-coding и AI Agents.
Тогда еще было модно говорить "если один микросервис упадет, остальные 9 будут продолжать работать, но с ограниченным функционалом". Когда встречаются сервисы, разработчики которых справились с этой задачей, это действительно приятно. Монолит все-таки падает целиком. Но с другой стороны, сейчас со всеми куберами, свормами, дублированием датацетров, автоскейлингом и прочим, даже уборщица шваброй в дц не сможет положить твой сервис. Понадобится кластер распределенных по датацентрам уборщиц
Пожалуй, на собеседовании после вопроса о микросервисах спрошу
А они вам не надоели ещё?
Или более жестко:
Вы не наигрались ещё?
Машалла... У вас изначально было не 15 микросервисов, а просто зоопарк приложений, общающихся между собой через RPC вызовы (вы же не называете СУБД микросервисом хранения данных, а что, довольно таки узкая задача). Архитектура - это как раз таки единый свод правил и принципов построения приложения или его частей. И если эти части реализуются кому как нравится - то это даже архитектурой назвать нельзя. Хотя, отсутствие архитектуры - тоже архитектура (архитектурлесс сервисес)
Основное отличие микросервисной архитектуры - это общение между микросервисами через шину сообщений: микросервису плевать кто отправил и кто получит сообщение, так называемая слабая связность. А то что вы изобрели - уже как лет 15, если не больше, изобретено в Django.
Прийти к выводу об отсутствии архитектуры на основании того что все микросервисы общались через RPC вызовы - сильно, но давайте разбираться:
Основное отличие микросервисной архитектуры - это общение между микросервисами через шину сообщений
Вы ошибаетесь. Взять определение того же Мартина Фаулера здесь:
In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.
То, каким способом взаимодействует приложение, не определяет микросервис это или нет. Более того, основной тип взаимодействия микросервисов - протокол HTTP. Но конечно вы можете настроить общение через шину сообщений, микросервис от этого не станет более микросервисным.
А то что вы изобрели - уже как лет 15, если не больше, изобретено в Django.
Ничего не изобретала, архитектуре модульных монолитов уже десятки лет, у меня вариант реализации паттерна, а не изобретение нового. Джанга молодец)
Если вы почитаете статью Фаулера полностью (рекомендую перевести в яндекс браузере), то вы увидете раздел Smart endpoints and dumb pipes, в котором как раз таки есть такие слова "Applications built from microservices aim to be as decoupled and as cohesive as possible / Приложения, построенные на основе микросервисов, должны быть максимально независимыми и согласованными" - это фактически означает, что вы не должны через rpc клиент дергать какой-то микросервис, либо делать это осознанно, в качестве исключения. И сбоку кстати висит плашка о том, чтобы не путали сервис ориентированную архитектуру а микросервисной, как раз таки намекая на независимые части. Ну сами посудите, какой смысл заменить в монолите вызов методов через память, вызовом методов через какой-то транспорт и назвать это микросервисом. Ну комон, это глупо.
Если вы решаете проблему реализации разных частей приложения разными командами и языками - то тут в первую очередь нужно говорит о сервис ориентированной архитектуре а не микросервисной. Кстати, вот вам какие-то ребята дали сервис, который они написали на несусветном языке, использую несусветные знания, которые не смогли реализовать в рамках модуля в вашем монолите - что будет, если вы вызовите их сервис, а они в это время будут делать деплой новой версии? То то же.
Ну и в целом, основная мякотка в монолите - это возможно запуска логики в рамках транзакции СУБД, а в микросервисах вам уже нужно самим обслуживать целостность и согласованность данных.
чтобы не путали сервис ориентированную архитектуру а микросервисной
по этому пункту признаю свое поражение)
Ну сами посудите, какой смысл заменить в монолите вызов методов через память, вызовом методов через какой-то транспорт и назвать это микросервисом.
Аааа возможно вас зупатал пункт "Все модули используют одну базу данных, а взаимодействие между ними представляет собой цепочку вызовов функций, а не сетевых запросов. " и вы думаете что здесь про RPC, а я то библиотечное апи имела ввиду. Нарочно там не хотела писать про вызов методов чтобы никто про апи методы не подумал, а вы про RPC подумали. Надо подумать как переформулировать. Все нормально с моим монолитом, он сам с собой общается, не переживайте )
Кстати, вот вам какие-то ребята дали сервис, который они написали на несусветном языке, использую несусветные знания, которые не смогли реализовать в рамках модуля в вашем монолите - что будет, если вы вызовите их сервис, а они в это время будут делать деплой новой версии?
Общение по HTTP. Ну деплоят, Polly подождет. Кстати, у меня есть апи-метод прокся для резолва таких сервисов, но я боюсь вызывать у людей паническую атаку. Хватит контроллеров в библиотеках на сегодня)
Приложения, построенные на основе микросервисов, должны быть максимально независимыми и согласованными" - это фактически означает, что вы не должны через rpc клиент дергать какой-то микросервис
Не убедил. Не понимаю как одно из другого вытекает.
А ещё композиция апи не микросервисный паттерн https://microservices.io/patterns/data/api-composition.html
На главной странице https://microservices.io/patterns/index.html приведена схема, где ядром Application Patterns является консистентность данных. Ну и в целом вся архитектура построена на обмене сообщениями. Композиция апи - это лишь малая часть, прием организации взаимодействия.
А еще мы не хотим зависимости для юнит-тестов тянуть в релиз билд.
Из крайности в крайность. Монолит надо побить на микросервисы, микросервисы слепить в монолит. Как волосы у женщин: вьются - надо распрямить, прямые - надо завить.
Пару раз зайдя техлидом в проект я тоже обнаруживал дикий оверкилл по количеству сервисов. Не запариваясь архитектурой просто побили от балды ориентируясь на названия папочек в репе. И пришлось двигаться в более монолитную сторону. Не монолит, но пять сервисов, вместо ~30 "микросервисов" (в кавычках, потому что микросевисная архитектура строже и уже, чем ее многие представляют), короче компромисс, с учетом целей бизнеса, ресурсов и прочего. Просто менять парадигму на противоположную, потому что текущая явно туго идет - это выстрел вслепую.
В C# проверка контрактов и запрет прямого обращения мимо них делается легко. Как и в Java.
Но пожалейте бедных пыпхпыхов игогошек и змееловов - сами виноваты! Там микросервисы вынужденная мера.
Я сам долго не мог понять пока работал с C#, нафига это всё. А вот занесло в крупный PHP проект и похоже, что понял.
И ещё
Как можно читать этого Фаулера, если он даже определения микросервисам не смог дать?
Весь бойлерплейт вынести в общий набор библиотек компании.
Все инфраструктурные части, коннекторы, консюмеры, прослушиватели в общий набор библиотек проекта.
Если сервис предоставляет АПИ, то он же обязан предоставить готовую для использования библиотеку для работы с собой (и выкинуть в нугет репозиторий)
Вуаля. Ни-ка-ких проблем, чтоб создать новый сервис и встроить его в инфраструктуру. В идеале, конечно, создание нового сервиса начинается с создания по шаблону и сразу переходом к написанию логики. Ой. ну прям как в монолите! :)
Основная сложность здесь, это развивать качественные соглашения и следовать им, вести разработку общих либ и.. думать о других разработчиках, думать наперёд. Когда вы думаете о других, или даже о себе (в будущем), то получается хорошая разработка.
Многие ошибочно считают, что у приложения есть только те пользователи, которых видит бизнес: клиенты, кастомеры, партнёры... Но ещё есть и другие пользователи, это обслуживание, сопровождение, мониторинг, администрирование — тоже пользователи, про которых обычно забывают. Разработчики являются пользователями своего же изделия с точки зрения разработки, его надо развивать, поддерживать. Если обо всём этом подумать, нет проблем ни с микро-сервисной архитектурой, ни с монолитной. И там и там есть свои плюсы в каждой конкретной ситуации.
нугет
В шарпе да
Что же делать тем кто пишет на PHP?
Там нет гарантий консистентности и изоляции
Что же делать тем, кто пишет на golang?
Там сплошные провокации на микросервисы.
На голанг своя специфика, на прикладном уровне думать приходится только о структуре, логике. О производительности, потоках, и прочих узкоспециализированных концепциях задумываться приходиться редко. Благодаря маленьким масштабам, компактным сборкам, это всё бодро скейлится.
На пыхе, если оставаться в парадигме выполнил задачу => умер, то совсем не надо париться ни о чём. Только не надо сувать PHP между другими приложениями, в интеграционный слой. Там ему плохо, узко, тесно и ваще.
Полностью отсутствуют какие-либо детали, чтобы можно было о чем-то судить.
Я стала злодейкой и теперь мои контроллеры лежат в библиотеках. Архитектурный паттерн SUFA в .net приложении