Комментарии 180
С другой стороны, появление этих ваших гитхабов и гибких методологий привело к rolling release-ам, точнее к отсутствию релизов как таковых. Есть поток отладочных версий библиотек с кучей багов, которые никто не собирается фиксить, а вместо этого просто выкатывают новую, несовместимую со старой версию со своими свежими багами.
Вы начинаете более-менее крупный проект, берёте свежайшие либы и, пока дойдёте до версии 1.0, выясняете, что ваши либы устарели уже на пару мажорных номеров. С монолитом просто так взять и обновиться нельзя, нужно переписывать кучу кода и заново его тестировать.
Микросервисы решают этот вопрос тем, что позволяют себя переписать на новой либе или вообще новом языке за те пару месяцев, пока версии ключевых либ считаются «свежими».
Плата за это — да, налог на девопсов, а также сложноуловимые баги «между» микросервисами, когда непонятно, кому вообще заниматься отладкой.
С микросервисами тоже просто так обновится нельзя, переписали сервиси — надо так же все тестировать, где гарантия что сервис переписан коректно.
> Микросервисы решают этот вопрос тем, что позволяют себя переписать на новой либе или вообще новом языке за те пару месяцев, пока версии ключевых либ считаются «свежими».
Пока переписываем микросервис — либы опять устаревают? тут наверное нужно гнаться не за либами — а найти компромисс между «старыми» либами и работающим функционалом.
Плюс спорный вопрос, что тестить проще. Если монолит целиком переписать и потом его тестировать — то ну его нафиг, так вообще не полетит. А если сделать roadmap для переезда на новую платформу(ради чего мы переписываем), то изменения можно будет да же под бизнесовыми задачам провести и протестировать.
Однако, в целом, вы пишите фактически только про изолированность, документированность и чистоту кода.
Однако, микросервисы — это уход, в первую очередь, от инфраструктурных проблем.
Потому что монолит — требует, чтобы одна единственная машина могла предоставить все необходимые пакеты(модули) и все необходимые ресурсы требуемые для решения задачи одновременно.
Когда речь идёт о каком-нибудь многоуровневом стэке технологий(когда одни библиотеки опираются на кодовую базу других) — все хорошо.
А вот как только вы используете разноплановые библиотеки из разных технологических стеков — запуск и развертывание монолитного решения становится задачей почти фантастической, т.к. постоянно вылезают противоречивые требования или прямые несовместимости библиотек.
А вот когда дело доходит до обработки больших данных… ух. Тут микросервисы, каждый из которых должен анализировать свой кусок данных на недорогих инстансах 4+4(4 vCPU+4GB RAM), или давать быстрый ответ для пользователей в своей географической зоне — незаменимы.
К тому же, в тех же направлениях распределенных вычислений фрагментация пакетов-модулей — гораздо выше, чем в «традиционных» областях, что создаст огромное количество проблем при попытке обновления каких-то библиотек в монолите.
Так что — все зависит от поставленной задачи, которая диктует выбор технологического стэка(или россыпи).
Если ваша задача решается стэндалон, или единичным сервером на «стратифицированном» технологическом стэке — вполне вероятно, что монолит — будет хорошим решением.
Если же нужна распределенная система, или большое количество несвязных модулей/библиотек — добро пожаловать в микросервисную архитектуру.
Ну и CI/CD, как правило, все-таки гораздо легче, как минимум по машинным ресурсам — решается на микросервисах.
Переход на микросервисы сам по себе ничего не упрощает, но превращает часть внутрипроцессных вызовов в медленные, ненадежные, плохо контролируемые на соответствие соглашениям сетевые.
И все это ради единственного преимущества: селективного горизонтального масштабирования.
Селективный деплой для монолита сложнее, но также возможен при аналогичном подходе к проблемам совместимости.
Я всегда думал, что "частичный отказ" подразумевает поломку сервиса, сопровождающейся простоем.
Если сервис "один из..", в микросервисной архитектуре — получаем как раз "частичный отказ". Если сервис "всего один", как монолит — то либо работает либо нет. Как может "частично" работать (а вернее "частично не работать") монолит в данном контексте — не понятно.
как монолит — то либо работает либо нет.
может же быть несколько экземпляров.
Как может «частично» работать (а вернее «частично не работать») монолит в данном контексте — не понятно.
ну например, повреждена БД.
операции с ней невозможны.
но все что не требует СУБД — успешно работает.
Если такое случится с каким-то неключевым микросервисом, то приложение будет работать пускай и не полностью.
С этим не все так просто.
Возьмем конкретный ясный всем пример — интернет-магазин.
Не работает хоть что-то из этого: корзина, каталог товаров, оформление товаров, прием оплаты-онлайн. У вас нет интернет магазина.
То, что работает при этом уведомление пользователей по СМС, уведомление пользователей по e-mail, полнотекстовый поиск, статьи блога, система рекомендаций товара, веб-сайт в целом — ситуацию не изменяет. Все равно у вас нет интернет-магазина.
Да даже с инет магазином: не работает приём оплаты: люди могут продолжать просматривать товары, набирать их и т. п. Пока они это делают, приём могут уже починить. Не работает корзина: могут хотя бы просматривать, выбирать (в смысле сравнивать разные товары и подходить к принятию решения). Не работает каталог: могут оформлять оплату те, кто успел набрать корзину до отказа. Ну и по идее при отказе микросервиса будет выводиться не обычная 500-я, а внятное сообщение о временной неработоспособности конкретной функции.
А вот если монолит падает, то в лучшем случае какая-то 500-я будет и работать не будет ничего. Естественно я о фатальных отказах, приводящих к сегфолтам, а то и паникам, в лучшем случае к выходу из процесса с ошибкой, а не о логических на уровне модулей.
Не работает корзина: могут хотя бы просматривать, выбирать (в смысле сравнивать разные товары и подходить к принятию решения). Не работает каталог: могут оформлять оплату те, кто успел набрать корзину до отказа.
Формально — да, как бы работает.
Но от простого просмотра каталога до реального заказа доходит хорошо если 1 из 1000.
Так что падение каталога — это фатально.
Слово «неключевым» заметили?
Да и привел пример, когда «неключевых» мало.
Их всегда мало, если сервис специализируется на одной услуге.
Если монолит целиком переписать и потом его тестировать — то ну его нафиг, так вообще не полетит.
Прежде чем рефакторить, нужно написать тесты или нет? Или в райффайзенбанк не пишут юнит, функциональные, интеграционные, автоматические тесты?
Так. Стоп. То есть юнит тесты на пакет/класс в коде вас не устраивают, а вот если вынести это в отдельное приложение и сделать такие же тесты, то все магически меняется?
Великолепная логика
Пример: для теста нужна БД
Для теста модуля монолита БД может быть не нужна совсем. Или нужна, но те же 10 табличек. Сервису же для тестов в любом случае надо базу и сетевого клиента.
Если для тестов модуля монолита нужны все 500 таблиц, то он плохо спроектирован. Такой же по качеству микросервис также захочет 500 таблиц из базы, которую будет делить еще с 50 микросервисами.
Микросервис байдизайн должен иметь выделенную базу, ну или не иметь базы совсем.
К примеру, один из них отвечает за регистрацию/авторизацию, а другой за обработку платежей
Практика-то довольно распространённая. Есть несколько бэкендеров, у них разная зона ответственности, поэтому они на каждую предметную область заводят свой репозиторий, используя при этом одну БД.
У этого же есть какое-то название? Почему это не может быть микросервисом?
микросервисы это тоже SOA
Для 2-х SOA-компонентов вам не нужна оркестрация.
Или для каждого теста писать свои миграции?
По логике, микросервис не должен лезть в чужие базы. Миграции у него должны быть свои, согласованные с версией этого микросервиса.
Если каждый модуль нуждается в той же базе, что и монолит в целом, проблема не монолитности, а в качестве проектирования.
Я не знаю, зачем вам для тестирования одного конкретного модуля надо запускать монолит целиком.
Модульность затем и нужна, чтобы разрабатывать и тестировать модули можно было независимо.
Модуль — это просто кусок кода, с торчащими наружу функциями или классами.
Вытащить из монолита модуль — на порядок более простая задача, нежели вытащить из него модуль и сформировать микросервис. Поэтому говорить «вырезать из монолита микросервис для целей тестирования» — некорректно.
Есть один процесс и это монолит.
А вот бинарных фалов с модулями может быть сколько угодно.
Еще в MS DOS были оверлеи.
В Windows появились dll.
В Linux также есть свои подгружаемые в один процесс бинарники.
Единственный бинарник на процесс в наше время экзотика.
Однако, никто ведь не мешает так категорично поделить и модули монолита, т.е. каждый модуль — со своими базами. Настроить деплой — это задача не сложнее аналогичной для микросервисов.
И его так же можно делать тестирование, без остальных модулей («монолита»).
ищущий среди своих инстансов тот, где он подключен, и дергающий его по сети
Если есть сетевое взаимодействие между инстансами, это уже не монолит.
Зачем дергать по сети то, что можно загрузить в память и вызвать напрямую? Интерфейс известен заранее.
Это ещё будет монолитом?
В контексте сравнения с микросервисами, которые представляют собой разные процессы, единая программа, скомпонованная из модулей вне рантайма больше похожа на монолит. Монолит в этом случае вполне может состоять из разных исполняемых модулей (физически разные файлы), это не играет роли.
Вообще спор монолит вс микросервисы больше просто обсуждение где остановиться в декомпозиции, а не плюсы или минусы декомпозиции в целом поскольку настоящих монолитов, не обращающихся по сети или локальным сокетам к сторонним процессам, очень мало осталось, по-моему. N-звенная архитектура, выделенная СУБД — уже не монолит, запускаемая по расписанию в отдельном процессе задача пускай того же бинарника — тоже.
Вот я более чем уверен, что подавляющее большинство в этом топике говоря о монолите, например, в вебе, имеют в виду что-то вроде: клиент в браузере, веб-сервер, апп-сервер, СУБД, какой-нибудь редис, скорее всего где-то крон в фоне, может даже очередь с воркерами отдельными. Отдельная система анализа логов и мониторинга, автоматического перезапуска при краше. И про всё это говорят «у нас монолит». При это ещё прикладывая усилия для того, чтобы части апп-сервера минимально зависели друг от друга, обновлялись на лету, не загружались пока не нужны и выгружались когда уже не нужны.
Когда-то почти перестали писать реально монолитные приложения, выделяя из них сервисы, а часто не выделяя, а удаляя из них «наколенке» реализованную функциональность и вместо неё подключая сторонний сервер типа веб-сервера или СУБД — а это уже сервисно-ориентированная архитектура. Микросервисная — лишь дальнейшее разбитие, начавшееся в тот момент, скорее всего, когда кто-то решил «а давайте СУБД у нас будет отдельным сервисом» или «а давайте UI вынесем в отдельный сервис». После этого уже не стало монолитов а спор монолит вс микросервисы превращается в спор о том, нужно ли один большой самописный сервис («монолитный» апп-сервер, бесполезный без кучи других сервисов) дальше разбивать на более мелкие сервисы или пора остановится.
Вот я более чем уверен, что подавляющее большинство в этом топике говоря о монолите, например, в вебе, имеют в виду что-то вроде: клиент в браузере, веб-сервер, апп-сервер, СУБД, какой-нибудь редис, скорее всего где-то крон в фоне, может даже очередь с воркерами отдельными. Отдельная система анализа логов и мониторинга, автоматического перезапуска при краше. И про всё это говорят «у нас монолит». При это ещё прикладывая усилия для того, чтобы части апп-сервера минимально зависели друг от друга, обновлялись на лету, не загружались пока не нужны и выгружались когда уже не нужны.
Не совсем так. Это не мы говорим "у нас монолит", это приходит фанатик микросервисов и говорит "у вас не микросервисная архитектура? Значит, у вас ужасный монолит!"
И про всё это говорят «у нас монолит».
Не скажу за всех, но я под этим подразумеваю, что бизнес-логика приложения не размазана по независимым приложениям. Интерфейсы занимаются вводом/выводом, БД — хранит состояние, кэши — прозрачно кэшируют.
Настоящих монолитов мало, как и настоящих микросервисных систем. Зато полно гибридов с массивными кусками, как-либо между собой интегрированными.
Берем и суем вместо обычного клиента БД собственный, возвращающий тестовые данные. В чем проблема?
По-моему, модульное тестирование всегда делают с подмененной БД, а e2e с настоящей. Ну а БД вообще не часть приложения.
Значит вы про е2е тесты.
Там по-любому потребуется полная БД и все микросервисы/монолит. И опять с микросервисами сложнее.
Реализация конкретного API микросервиса может делать вызовы к другим микросервисам и для полноценного тестирования извольте поднимать весь оркестр.
А у модуля никакого WebAPI и тем более базы может вообще не быть. Достаточно обычных ООП-интерфейсов. У монолита WebAPI будут трогать только E2E-тесты.
У модуля может быть любой API в том числе WebAPI, и база своя, ну или свои таблички в общей базе. Вот модуль аутенфикации и авторизации. Ему нужен свой ендпоинт, чтобы браузер или иной клиент стукнулся, ему нужна база, чтобы хранить юзеров, пароли, роли, права и связь этого всего друг с другом. Как вы будете тестировать авторизацию без WebAPI и базы? Как проверите, что, например, роутинг корректно настроен и объекты на базу корректно смаплены? и вообще всё это друг с другом связано. Это ещё не e2e с точки зрения всей истемы, потому что UI не задействован, но это тест WebAPI. Грубо, после его прохождения бэкендера можно на другой модуль или проект переводить, а не ждать пока фронтендеры что-то сделают.
Модулю не нужен EndPoint для браузера.
Модулю не нужна база.
Модулю ничего не нужно, кроме двух списков контрактов:
- То, что модуль обязуется реализовать.
- Необходимые модулю для обеспечения пункта 1
Есть модули, которые специализированы на доступе к базе или реализации внешних точек доступа. Но для модулей, в отличие от микросервисов, это экзотика.
Например, модуль авторизации 100% будет отвязан как от конкретной точки доступа, так и от конкретного хранилища данных.
это уже будет не тестирование монолита, а только какой-то его части.
Двумя сообщениями выше:
Даже сервис тестировать сложнее, чем модуль внутри монолита, решающий те же задачи.
Не надо сравнивать тестирование монолита целиком и одного микросервиса.
Один микросервис есть смысл сравнивать с одним из модулей монолита.
Протестируем как модуль интегрируется с базой в лучшем случае, но не проверим как он работает с базой.
В том-то вся и штука, что микросервис надо тестировать с клиентом и базой, у модуля же клиентом будет тестовый фреймворк, а с базой напрямую ему работать без надобности.
Вот как модулю авторизации не работать с базой юзеров
Очень просто: модулю авторизации хватит и абстракции над хранилищем.
Если на тесте микросервиса мы проверяем весь флоу от отработки сетевого запроса от клиента до работы с базой, значит и для модуля мы проверяем то же.
Нет, конечно. Для модуля даром не нужно проверять всю эту микросервисную инфраструктурную мишуру. Ибо модуль авторизации ни за точку интеграции, ни за базу данных не отвечает.
Не делаете реальный http-запрос при тестировании модуля, а стучитесь к роутингу как-то напрямую — не делайте его и при тестировании микросервиса
А вот здесь все с точностью до наоборот. Микросервис — это модуль с навернутым на него веб-API и хранилищем данных. Так что если тестировать сервис, то в отличие от тестов модуля, придется проверять и это.
На ваш модуль веб-API и хранилище данных наворачивается и в микросервисе, и в монолите. Отличие только в том, что в микросервисе он один, а в монолите шарит инфраструктуру с соседями. Почему вы предлагаете одну и ту же бизнес-функциональность тестировать по разному?
Не хватит ему абстракции.
Еще как хватит. У монолита снаружи видно то, что у микросервисов есть в API Gateway.
Все остальные API внутрипроцессные.
С базой все точно также — бывают модули, требующие себе базу и таблицы, но в отличие от микросервисов, это тоже экзотика.
Почему вы предлагаете одну и ту же бизнес-функциональность тестировать по разному?
Потому что микросервис и модуль в составе монолита — это разные вещи.
В случае монолита у нас будут
- Модульные тесты на классы
- Интеграционные тесты на модуль
- End2End тесты на приложение
Для микросервиса c той же функциональностью:
- Модульные тесты на классы.
- Интеграционные тесты на модуль.
- Интеграционные тесты на микросервис.
- End2End тесты на приложение.
небольшой сервис тестить всяко легче монолита
Ну вы так же можете тестировать монолит всего лишь юнит-тестами.
Нет? Хотите интеграционные?
А почему с микросервисами не считаете нужным интеграционные?
Потому что это гораздо сложнее?
Мартин Фаулер хорошо разжевал что не все так просто
habr.com/post/261689
И ребята из Фланта
habr.com/company/flant/blog/427283
За все приходится платить.
В том числе и за видимую «простоту деплоя одного сервиса».
Серебряной пули так все еще и нет.
Где-то что-то имеет какие-то плюсы. Но имеет и минусы.
я клоню к тому, что в случае с микросервисами тестов меньше, и нагрузка на их содержание меньше, но нагрузка на инфраструктуру растет
Вы упускаете более высокую сложность интеграционных тестов для микросервисов.
Когда что-то в полноценном тесте всей системы пошло не так — разобраться, что виноват не ваш измененный микросервис, а косяк где-то в том (который вы вроде и не меняли), что вызывает тот, который вызывается тем, что вызывается из вашего — не проще.
Да, да, да. Это так же сложно выглядит при отладке как и сложно выглядит мое описание проблемы.
Что-то не спасают. Поэтому появились сервисы для трассировки.
логи спасут мир
Конечно, конечно.
При этом, чтобы понять что там происходит, вам нужно совместить логи с разных микросервисов, чтобы было понятно, что они относятся к одному и тому же запросу.
И хорошо, если речь идет только об «линейно проходящих» запросах.
А если это фоновые процессы, запускаемые при разных условиях? Или если это несколько параллельно порожденных вызовов внутри микросервисной системы?
А если вам не хватит информации в логах? Добавить, сделав логи более подробными — не проблема. Но вам придется изменить и перезапустить некий третий микросервис только для того, чтобы отладить первый.
Никто не говорит, что в микросервисах невозможно отлаживать в принципе.
Просто микросервисы выглядят как бы простыми в отдельности, если забыть о том, что нам-то (бизнесу, заказчику) нужна работающая вся система в целом.
Когда вы переходите на микросервисы — сложность никуда не уходит.
Просто из монолита сложность размазывается между микросерисами и связями между ними.
Был большой комок грязи в монолите.
А стал большой комок грязи в связях между компонентами.
У микросервисов есть свои преимущества. Которые являются недостатками в монолитах.
Но микросервисы вовсе не универсальная серебряная пуля. Так как появляются и новые недостатки. Которые в монолитах не так остры.
Серебряной пули, волшебной «лучше всех» технологии не существует в сравнении монолиты vs микросервисы. Нужно смотреть по конкретной задаче.
Вместо find usages и проверки всех использований вам надо каким-то образом при любом изменении бегать по графу зависимостей всех ваших сервисов, причём рекурсивно.
Вы начинаете более-менее крупный проект, берёте свежайшие либы и, пока
дойдёте до версии 1.0, выясняете, что ваши либы устарели уже на пару
мажорных номеров. С монолитом просто так взять и обновиться нельзя,
нужно переписывать кучу кода и заново его тестировать.
Что мешает стараться писать код без прибивания гвоздями к библиотекам и вовремя их обновлять, история умалчивает.
Монолит — небольшой комок грязи(big ball of mud)
Так, всё-таки, большой или небольшой?
Главное не переезжать на микросервисы с количеством людей меньше микросервисов… ну вот решили мы сделать новый проект на микросервисах… всё красиво развернули, докер, куча баз, свежее апи, все дела, штук 10 сервисов пока. А разработчиков: один фиг 1-2 на бэке+сайт, плюс мобильщик, который так же должен заниматься своей частью бэка, если ему что-то нужно для мобилы по апи. И в итоге 80% времени чувак с сайта и мобильщик бессмысленно тратят время на понимание что идёт не так во всех этих микросервисах, которые намутил единственно разбирающийся в этом девопс. Ибо раньше они просто вставляли один метод в контроллер и всё, а теперь там 5 перекрестных вызовов между микросервисами, чтобы собрать все данные.
У сервиса должно быть понятное API — если нет, то это боль которая превращает наши сервисы еще в больший комок грязи.
И если мы интегрируемся с сервисами, мы должны знать только контракт и особо разбираться что там под капотом происходит нет смысла.
По поводу количества людей на проекте, думаю это не корректно — по человеку на сервис, небольшая команда может пилить и 100 сервисов, нужна только хорошая документация, выстроенный процесс. Сервисы не очень большие и после разработки все разом не очень часто меняются.
Тут наверное вопрос к спеке, микросервисы должны упрощать работу, если нужна информация по пользователю.
Если вам вместо того, чтобы просто вызывать функцию…
… нужно сделать вызов по сети и отработать ситуацию с ошибками, возможно повторить через некоторое время и послать в этот раз запрос на другой экземпляр микросервиса — это несколько другой объем работы (не только по созданию, а еще и при отладке), чем просто вызывать функцию.
Это не одно и то же, что и отличная спецификация (которая еще и постоянно меняется).
Тут проблема совсем в другом.
Ваш оппонент правильно сказал:
Микросервисы отличный способ распределения задач между разработчиками, когда разработчиков очень много.
Но микросервисы — плохо когда разработчиков существенно меньше по количеству, чем микросервисов, так как на каждом из микросервисов идут дополнительные накладные расходы на создание и отладку, что при 1 разработчике на 10 микросервисов делает проект малоэффективным.
И это не решается сколь угодно точной спецификацией. Хотя бы посмотрите на отладку? Все уже написано по спецификации. На этапе отладки спецификация вам уже не поможет.
Если при проектировании были учтены все эти факторы и была выбрана подходящая архитектура для проекта, которая решает задачи проекта, то и поддержка, тестирование, разработка не будут вызывать боль.
Монолиты так же живут хорошо в облаках, ток стоит это других денег, а Микросервисы это не вынужденый архитектурный стиль, микросервисы хорошо маштабируются и не нужно перепрлачивать за серверное железо, позволяют более грамотно утилизировать ресурсы.(это частный случай)
А про облака и тп — это наверное уже про стоимость владения, которая складывается не только из поддержки, но сервера, лицензии и обновления — и это может быть дороже чем содержать команду и расчитывается она не на один год, а на период(года).
микросервисы хорошо маштабируются и не нужно перепрлачивать за серверное железо
Лукавите. Что бы наносервис, микросервис, да вообще любой сервис масштабирование, нужно масштабирование заложить в архитектуру. Если это не закладывается, то и микросервис невозможно будет от масштабировать. Если это заложить в монолите, то и монолит можно будет хорошо масштабировать.
нужно перепрлачивать за серверное железо
Переплата происходит в случае вертикального масштабирования. Если же при горизонтальном масштабировании не нагруженный монолит потребляет куча ресурсов, то это косяк разработчиков, которые не занимаются оптимизацией.
Вроде звучит как монолит на Java, но я видел монолиты на Java, которые не съедают все ресурсы сервера.
А кто говорит про «ниоткуда»?
Вы:
два модуля в монолите, каждый хочет по 8
Сервис ничего не делает, но уже съел память. Уход на X и 2X ничего не меняет. Может быть вы приведёте реальный пример, где такое потребление ресурсов, это не архитектурная ошибка.
Я вообще не понимаю о чём мы тут спорим? Что нельзя сэкономить на ресурсах перейдя на микросервисную архитектуру и масштабируя только отдельные модули? Или что идеальный монлит можно превратить в набор микросервисов через конфиги?
Единственное, в чем будет разница по памяти между запущенным инстансом монолита и микросервиса, которые делают одно и то же — это в размере бинарника. Именно на эту разницу и увеличится потребление памяти. Память стоит копейки. Ради того, чтобы ее сэкономить вы чудовищно усложняете разработку и поддержку, вводите кучу сущностей, процессов и инструментов, а это как раз стоит дорого.
Как вам вообще удаётся бизнесу продавать такие вещи?
Микросервисы — это вынужденный архитектурный стиль для написания распределенных приложений, если нужно написать приложение, которое должно работать в облаке (cloud native), в других случаях нужно 200 раз подумать
Вы вполне можете запускать монолит в облаке.
Разумеется, монолит должен изначально поддерживать совместную работу множества инстансов.
Серьезные монолиты (у того же Фейсбука), разумеется, живут не на одном единственном сервере.
Ещё один аспект — микросервисы позволяют использовать GPL код совместно с вашим закрытым.
Там все не просто с лицензиями..., мысль отличная, нужно подумать над ней. Но в риалиях современного мира, я видел когда софт в оборонку поставляется с нарушением лицензий, в военских частях стоят откровенной пиратский софт.
Монолиты так же живут хорошо в облаках
Я это и не опровергаю.
а Микросервисы это не вынужденный архитектурный стиль, микросервисы хорошо масштабируются
Вот поэтому они хорошо и маштабируются. Мы вынуждены придерживаться определенного архитектурного подхода, чтобы это обеспечить, поэтому Микросервисы — это вынужденый архитектурный стиль ИМХО.
А про облака и тп — это наверное уже про стоимость владения, которая складывается не только из поддержки, но сервера, лицензии и обновления
Да кто про это говорит? Я же говорю, что если приняли решение идти в облоко, то микросервисы и еще 200 раз подумайте. Я не к тому, что если облоко, то 100% микросервисы, совсем нет.
Монолиты так же живут хорошо в облаках
Я это и не опровергаю.
а Микросервисы это не вынужденный архитектурный стиль, микросервисы хорошо масштабируются
Вот поэтому они хорошо и маштабируются. Мы вынуждены придерживаться определенного архитектурного подхода, чтобы это обеспечить, поэтому Микросервисы — это вынужденый архитектурный стиль ИМХО.
А про облака и тп — это наверное уже про стоимость владения, которая складывается не только из поддержки, но сервера, лицензии и обновления
Да кто про это говорит? Я же говорю, что если приняли решение идти в облоко, то микросервисы и еще 200 раз подумайте. Я не к тому, что если облоко, то 100% микросервисы, совсем нет.
Они её ни добавляют ни уменьшают. Сложность перераспределятся с уровня кода и его архитектуры, на уровень инфраструктуры. В итоге часть работы снимается с одних людей и ложится на других.
В одних случаях это хорошо, в других — плохо.
На уровне ифраструктуры это как раз перераспределение.
На уровне кода это одно и тоже, если код нормально написан и протокол взаимодействия устаканился.
Если уже написан и отлажен — да.
А ошибки сети, а балансировка? Как это все отлаживается — неужели нет разницы?
Обработка ошибок сети реализуется один раз
Почему?
А если логика задачи требует повторных попыток?
А инициализация соединения/авторизация в соединении, зачем это делать каждый раз?
И пр.
Вы как-то слишком упрощаете.
Конечно можно реализовать так, чтобы вызов удаленного микросервиса выглядел как вызов процедуры.
Но в таком случае вы теряете много контроля над процессом.
То они были бы и без микросервиса.
>инициализация соединения/авторизация в соединении, зачем это делать каждый раз?
И действительно, зачем? Достаточно одного раза, в чём проблема? Не надо в каждом месте вызова соединение создавать.
>можно реализовать так, чтобы вызов удаленного микросервиса выглядел как вызов процедуры.
Я не это предлагаю. Выглядеть он должен как вызов микросервиса. Но сил программиста на написание этого вызова можно тратить столько же, сколько и на вызов локального кода.
То они были бы и без микросервиса.
Внутренние вызовы не в пример надежнее, чем внешние RPC.
Но это не значит, что их ошибки можно не обрабатывать. Всё равно надо. Какая разница, как часто фейлится логика: 1 из 1000, или 1 из 1000000. На больших числах ошибки всё равно будут.
Внутренние это на одном железе которые?
Это довольно простой случай. Та же база далеко не всегда находится на том же железе, что и работающий с ней код. Коду нужны одни параметры железок, базе — другие.
Вот микросервисы, кстати, ещё можно так разворачивать — код + небольшая база (и то спорный вопрос).
Я думаю, большинство людей всё-таки имеет в виду более широкую трактовку.
Достаточно одного раза, в чём проблема?
В сетевой микросервисной среде у вас априори более слабые возможности по контролю прохождения вызовов.
Если вы это не учитывайте — запросто можете получить плохо работающую систему.
Если вы это учитывайте — то пишите больше кода.
Далее идеёт код логики: ветка если всё хорошо, ветка если операция провалилась (условно). Ветка для обработки ошибок писалась бы и в случае монолита.
Для примера: в монолите пишется код для обработки ошибок при работе с базой, в микросервисной архитектуре — для ошибок при работе с сервисами. Частота ошибок может быть разная, но код писать всё равно надо и во многих случаях он выглядеть будет одинаково.
если логика задачи требует повторных попыток?
То они были бы и без микросервиса.
Не были бы. В монолите была бы вызвана функция и все. В микроскопическое надо учитывать, что ваш сервис может рестартовать. В каждом случае прийдется решать отдельно как делать повторные вызовы: сколько ждать, сколько раз повторять, нужно ли вообще что-то делать если это ошибка DNS и т.п.
Для большинства случаев достаточно выработать соглашение в проекте по стандартному поведению в случае ошибок и закрепить его в коде. Это делается 1 раз.
Для особых случаев всегда приходится применять особые меры и решения, безотносительно того есть там обращение к микросервисам или нет его.
И само собой, микросервис — не серебрянная пуля. Если он реально мешает в каком-то частном случае, то не надо этот микросервис выделять.
В текущем проекте, работа системы должны идти 24x7, и микросервисы позволяют мне производить обновления на горячую (запустил новую версию параллельно старой, новая версия включается в балансировку, старая останавливается и удаляется), с монолитом такой сценарий намного сложнее.
Балансировку нагрузки в монолите можно реализовать по сути только на уровне всего сервиса, поднять рядом такой же сервис и чем-нибудь разруливать входящие запросы (NLB, ngnix и т.п.). Микросервисы же позволяют делать все намного гибче, если анализ показывает что узким местом является конкретный сервис, достаточно просто запустить его копию, по рессурсам намного менее затратно.
На прошлом проекте был проект бэкофиса, с небольшой нагрузкой, и с временем простоя ночами, когда не было пользователей, монолит подходил идеально.
В общем мысль такая, что архитектуру всегда нужно выбирать исходя из текущей задачи, а не из трендов в статьях.
микросервисы позволяют мне производить обновления на горячую (запустил новую версию параллельно старой, новая версия включается в балансировку, старая останавливается и удаляется)
Blue-green deployment это называется.
С монолитами вы тоже можете это делать. Точно так же.
когда же методу требуется
5 перекрестных вызовов между микросервисами, чтобы собрать все данные.— это верный признак что что-то пошло не так
… а так и кусок вполне ощутимого по размерам монолита вполне может являться микросервисом для других приложений — по сути это все публичные API крупных интернет-компаний (метрики, картография итп), с тем лишь исключением что их работа — не совсем собственная забота
Главное в этом деле — сменить работу раньше чем компания столкнется с последствием твоего решения. Тогда можно будет на митапах бодро рассказывать как внедрил микросервисную архитектуру, пока ищешь новую жертву.
Два чая этому господину. Вот так взяли и структурированно и понятно описали именно то, что мне каждый раз приходит в голову, когда слышу очередные истории успеха от адептов микросервисов. Единственный вменяемый аргумент это возможность проще скейлится и делать это динамически + нет привязки к одному стеку company wide. Но это плюсы, которые действительно полезны на большом масштабе, а не в проекте уровня CRM система на заводе
Единственный вменяемый аргумент это возможность проще скейлится и делать это динамически + нет привязки к одному стеку company wide.
Масштабироваться можно и монолитами. Не столь идеально попадать в аппаратные ресурсы, конечно. Но горизонтальное масштабирование все так же делается и монолитами.
Стек — не столь большая проблема. Если уж вы принципиально считаете, что вот этот кусок кода лучше переписать на чем то другом — ну отделите его в отдельный сервис (пусть не микро).
Полностью согласен. Это вопрос масштаба исключительно
Как делаешь, так и получается. Микросервисная архитектура это про то как иначе поделить большую работу между маленькими командами. Классический просчет при переходе от монолитной архитектуры к микросервисам — оставить процессы разработки и принципы владения кодом без изменения. Тогда к текущим затратам добавится расходы на девопс, интеграцию, тестирование, мониторинги, документацию и много другого подобного затратного счастья. Если бизнесовые потребности требуют менять over9k микросервисов ради одной фичи, что то не так в вашем подходе.
Это занимает много времени и порождает желание написать свои костыли в виде каких-то генераторов конфигов.
Вот как вы живете с этим? Может есть таблетка от этого?
А ежели сервисы настолько переплетены, что для разработки нужно поднять почти их все, то наверное действительно надо в архитектуре что-то исправить.
В логике бизнес-задачи это может быть изначальным.
Если основная цель вашего проекта — оказание одной-единственной основной услуги и вы проводите проверку функционала этой самой основной услуги, например.
Тогда все большая часть модулей вашего проекта направлены именно на это.
Ибо зачем вы остальные-то модуля писали вообще, если без них можно обойтись?
Пример интернет-магазина habr.com/company/raiffeisenbank/blog/427953/#comment_19310299
Не так уж много частей не задействовано, если мы проверяем ключевую операцию для такого проекта — как протекает оформление товара в целом.
В айти есть всего несколько количественных категорий: ноль, один, много и дофига. При переходах их одной в другую требуются принципиальные изменения. Нельзя просто так взять и распилить монолит на несколько кусков с кучей связей и назвать их микросервисам. Осколочная архитектура думаю будет более подходящим названием.
В монолите все это делается один раз, в микросервисе десятки, а то и сотни раз за цикл обработки одного запроса.
Ничего страшного.
Компьютеры давным-давно уже настолько шустры, что эти вещи мало кого волнуют.
Бизнес согласен платить больше за железо — лишь бы выйти на рынок раньше, лишь бы получить хоть как-то работающую систему, лишь бы иметь возможность подстраиваться под рынок оперативнее.
Чем получить систему более эффективно использующую железо, но позже.
Итог — той компании нынче не существует. А жаль и идеи хорошие были и коллектив сильный. А бездумный микросервисный подход живее всех живых и утопит еще не одну компанию.
Я не против микросервисов, и красиво и местами действительно годно. Но это не серебряная пуля на все случаи.
У всех виденных мной расчет экономики строился как минимум на не увеличении серверного парка, тепла, места, числа сетевых интерфейсов…
Тут есть всего два варианта — либо уважаемые эксперты не в курсе очевидного минуса, либо они наглые обманщики. Выбор варианта по вкусу.
Википедия:
Архитектура постоянно подвергается критике с самого момента её формирования, среди новых проблем, которые возникают при её внедрении отмечаются:
сетевые задержки[5]: если в модулях, выполняющих несколько функций, взаимодействие локально, то микросервисная архитектура накладывает требование атомизации модулей и взаимодействия их по сети;
В целом же по меркам ресурсов микросервисы могут приводить к их экономии, если минусы издержек с лихвой компенсируются плюсами от раздельного масштабирования.
Грубо, если монолит из M модулей, работающий в N инстансов (в целях производительности), вы разобьёте на M микросервисов в тех же N инстансах каждых, то вы практически гарантированно получите большее потребление ресурсов. Но если при разбиении монолита только несколько модулей запустите в N инстансах, а остальные в 1, то вполне можете покрыть издержки на микросервисную архитектуру без потери общей производительности, но, возможно, со значительной общей экономией ресурсов.
Все новое, хорошо забытое старое.
Блеск и нищета микросервисов
COM/DCOM (вернее систему, построенную на базе этих интерфейсов) можно считать с натяжкой имплементацией, частным случаем сервисной архитектуры. И часть проблем COM/DCOM микросервисная архитектура решает чуть ли не определению микросервиса (некоторым из них :) ). Если так хочется считать COM/DCOM предком MSA, то это не хорошо забытое старое (тем более что оно активно продолжает использоваться), а переосмысленное и улучшенное, даже просто по теории: часть ограничений сняли, но ввели новые.
Микросервисы делают мир проще (а вот и нет)