Pull to refresh

Comments 101

Отрезаем кусочки от монолита и выносим в отдельный сервис, если выясняется, что аналогичная функциональность требуется более чем в одном месте системы «состоящей из 2..3-х монолитов». Размер «глыб» кардинально не уменьшается, но хотя бы не растет драматически. А вот в ситуации с одним монолитным приложением, уже не все так однозначно, поэтому полностью поддерживаю посыл в статье.
PS: Документировать кстати все равно надо, как и решать вопрос производительности (время доступа).
UFO just landed and posted this here
А может просто не стоит всё так однозначно делить? Можно, например, посмотреть на процессоры, и взять на вооружение архитектурный принцип big.LITTLE, большое ядро для базовой логики и микросервисы для расширенной.
big.LITTLE это принцип кластеризации. То есть мощные ядра поместить в один кластер, который работает под большой нагрузкой, а энерго-эффективные ядра для простых задач закинуть в другой кластер. Перенося эту архитектуру, вы получите 4 монолита и 4 микросервиса, с балансировщиками нагрузки для каждого кластера. Только смысла в такой архитектуре нет. Каждый микросервис будет копией остальных 4х. Это избыточно.
На самом деле, в современной разработке с облачными технологиями всё чаще применяется serverless архитектура. Как по мне — это хорошая альтернатива микросервисам.
serverless архитектура. Как по мне — это хорошая альтернатива микросервисам.
Но ведь то, что маркетологи называют «serverless» — это в 90% случаев и есть крайний случай микросервисов, «по отдельному сервису на каждую функцию». Как он может быть им альтернативой?
UFO just landed and posted this here
А еще все новое изначально не настолько развито как старое и потому проигрывает. Со временем новая технология развивается и замещает старую. Отказываться от нового все-таки нельзя, но и внедрять в бой не глядя тоже глупо. Надо врубать мозг и осторожно, там, где от этого будет максимальная польза и минимальный возможный вред, пробовать.
Как-то так получилось что я уже на 3 месте работы переписываю микросервисы обратно на монолит. По какой то причине многим разработчикам кажется что, распределение сложных вычислений с большими объемами данных через микросервисы, связанные по api http или даже json-rpc через http, это нормальная идея. В итоге возвращение на монолитную конструкцию с многопоточностью обычно дает прирост производительности раз в 10.
В итоге я пришел к очень простому выводу. Микросервисная архитектура она не проще монолитной — она сложнее. В начале научитесь делать монолиты, а потом уже беритесь за микросервисы если они нужны. В противном случае вместо гибких микросервисов получается «копролит», эдакий плохо спроектированный монолит только с вызовами функций по сети.
Почему никто не вспоминает о джуниорах когда наворачивают по 5 слоев абстракции?
Потому что мидлы которые наворачивают по 5 слоев абстракции думают что они сеньоры как минимум. Не пристало им думать о каких-то там джунах. К их божественному коду таких даже близко пускать нельзя.
UFO just landed and posted this here

Вот только эти 5 слоев абстракций не гарантируют того, что не придется раскапывать/переписывать половину модуля

Не гарантируют, но уменьшают вероятность.
UFO just landed and posted this here
5 слоев абстракции намертво прибитые гвоздями.

Сталкивался и с тем и с тем.
Много слоёв абстракции? Чтобы что-то добавить, или изменить, нужно поправить 5 строчек, но может уйти не один час, чтобы найти места, где надо поправить эти строчки.
Плоское и намертво прибитое гвоздями? Казалось бы, рефакторинг и Find&Replace, а на деле копаться примерно столько же, сколько и в первом случае.

Разница в том, что вы правите 5 строчек, тестируете и работает везде. Плоское надо тестировать все.

Да! Лучше писать лучше, чем хуже! Но слои при этом не виноваты.
И не факт что работать с плоской архитектурой медленнее.
Пример из практики.
В клиенте перепутаны настройки, при выборе А выдает результат Б, при выборе Б выдает результат А. Казалось бы, найди да поправь. Но из увлечения бывших программистов уровнями абстракции человек, которому предложили это поправить сказал «нужна неделя, чтобы разобраться, как оно работает». При этом протестировать настройку на всех конфигурациях — день.
Да, чтоб потом мельчайшее изменение требовало переписывания пяти слоёв вместо одного.
Не думаю, что микросервисы чем-то особо выделяются от других «крутых» штук. Вы видели реализации «чистых архитектур» и «чистый код»? Там точно так же 5 слоев абстракций и джунам ничего не ясно и их нужно учить.
С другой стороны, задачи у сеньоров и мидлов не в том, чтобы писать код понятный джунам, а в том, чтобы это все приносило в конечном счете деньги и лучше больше, чем меньше. Архитектуры и подходы, понятные только профессионалам, разрабатываются, чтобы экономить время и деньги.
А джуны научатся. В этом их главная задача.
ну почему же не думают, очень даже думают при этом злобно хихикают!
UFO just landed and posted this here
Есть. Генерация низкоуроввневой библиотеки клиента микросервиса в процессе сборки микросервиса.
Как-то юзали swagger-codegen для этого, такой ад.
А что мешает вынести контракт в отдельную сборку (библиотеку) использовать ее клиентами?
UFO just landed and posted this here
Не нужно согласовывать все интерфейсы и пытаться как-то их протестировать. Нужно научиться писать приложения без багов, в той парадигме что вместе тестироваться они не будут. Пишите хорошее API, полностью документируйте пограничные случаи и не ломайте совместимость. Тестирование своего же API вам в помощь.
Нужно научиться писать приложения без багов

Спасибо за правильный совет. Я вам премного благодарен, теперь все в моей жизни будет хорошо, а логи чисты от ошибок!
UFO just landed and posted this here
Скажите, кто вас такому учит? Вот серьезно, кто?

Расскажу один случай из своей практики. Был лидом на одном проекте/стартапе. Проект был «запущен» до меня. Проблем в нем было вагон и маленькая тележка. После анализа был предложен план, что как улучшить/переписать итд. Далее почти дословно:

(Я — тим лид, З — заказчик он же менеджер)

Я: Так же в это время входят тесты, что бы протестировать и выявить потенциальные проблемы.
З: Какие на# тесты мы стартап и у меня нет бюджета на тесты.
Я: O_O

Прошло три месяца. За это время в команде трудилось два джуниора, два мидла и один сеньор (моем лице).

При первом тестировании фокус группой было выявлено 100500 багов. Думаю вы догадываетесь что сказал заказчик. Но я все же напишу.

«Мне сказали что вы классные девелоперы, а вы тупые дебилы! Вы не умеете писать код!». Надо ли добавлять, что с проекта я конечно же ушел.

100500 багов — это многова-то. Over 9000 — ещё куда ни шло.

100500 это частный случай over 9000
Вы описали случай не имеющий никакого отношения к тому, о чём я написал.

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

UFO just landed and posted this here
Спорно. Зависит от компании, от так называемой должностной инструкции.

Тесты бывают разные. Должен ли программист писать автоматизированные black box тесты и тесты внешних интерфейсов (от приёмочных тестов API микросервиса или Selenium тестов веб-UI до сложных интеграционных или простых BDD тестов) — действительно, зависит от компании и должностной инструкции. Но unit-тесты писать должен именно программист, более того, именно тот, который написал тестируемый этими unit-тестами код.

Это если в компании вообще требуются писать юнит-тесты. Плюс есть вариант, когда пишет юнит-тесты, тот, кто ставит техническую задачу, а задача программиста по сути — обеспечить прохождение этих тестов разумным способом.

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


Это если в компании вообще требуются писать юнит-тесты.

Запрет писать тесты в компании, которая разрабатывает что-то кроме прототипов со сроком жизни в пару месяцев — просто ещё один пример оторванных от реальности требований, которые только вредят компании. Да, компания имеет право выдвигать любые (в рамках закона) требования к сотрудникам, но сотрудники имеют ответное право пойти работать в компанию с более устраивающими их требованиями. Я лично в таких проектах, где нельзя писать тесты и нет CI/CD, принципиально не участвую.


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

Возможно, Вы имели в виду BDD тесты (низкоуровневые приёмочные тесты для публичного API класса/пакета/библиотеки, технически реализованные или в традиционном для BDD стиле "на языке заказчика" или в стиле обычных юнит-тестов) — там это нормально. Но в случае юнит-тестов это практически нереально на практике — такое можно практиковать только в очень крайних случаях, например при обучении студентов.


Задача юнит-тестов подтвердить, что написанный программистом код работает именно так, как ожидает написавший этот код программист. Учитывая слово "ожидает" написание юнит-тестов другим программистом становится значительно менее эффективным, т.к. другому намного сложнее угадать "ожидания" первого. Учитывая слово "код" является нормальным писать юнит-тесты к любому коду, включая внутренние вспомогательные функции/методы, не являющиеся частью публичного API класса/пакета/библиотеки — конечно, с учётом того, что перебарщивать с тестированием внутренних подробностей реализации не стоит, иначе тесты станут слишком хрупкими и их поддержка станет слишком дорогим удовольствием.


В отличие от задачи юнит-тестов, задача BDD/приёмочных тестов — подтвердить что код делает то, что нужно заказчику. В теории ожидаемое программистом поведение кода должно соответствовать нуждам заказчика, но на практике это разные вещи, поэтому и тесты для них тоже разные. Опять же, в теории, должно быть достаточно BDD/приёмочных тестов, но они ограничены тестированием публичного API, чего не всегда хватает и/или слишком усложняет и/или слишком замедляет тесты, плюс далеко не всегда "что нужно заказчику" в принципе известно с необходимой для написания BDD-тестов детальностью.

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

Решить, что нужно писать тесты, программист, конечно, может. Но вот, допустим, решить, что их можно закоммитить в общую ветку, не говоря о внедрении в CI/CD процессы, часто решает кто-то другой. Пускай даже peer-коллега, проводящий ревью. Другая крайность — формальные требования к уровню покрытию кода, когда программист должен писать юнить-тесты, если не на весь свой код, то на какой-то процент.


Но в случае юнит-тестов это практически нереально на практике — такое можно практиковать только в очень крайних случаях, например при обучении студентов.

Ну почему только при обучении студентов? Придумал архитектор API, написал тесты и отдал на реализацию.


Задача юнит-тестов подтвердить, что написанный программистом код работает именно так, как ожидает написавший этот код программист.

Не согласен. Задача юнит-тестов в данном контексте, подтвердить, что написанный программистом код работает именно так, как ожидает написавшие эти тесты программист.


написание юнит-тестов другим программистом становится значительно менее эффективным, т.к. другому намного сложнее угадать "ожидания" первого.

Как по мне, то ровно наоборот. Формализованные ожидания куда эффективней реализовывать, чем что-то переданное обычным текстом или вообще устно.


В отличие от задачи юнит-тестов, задача BDD/приёмочных тестов — подтвердить что код делает то, что нужно заказчику.

Можно рассматривать в этом смысле юнит-тесты как приёмочные тесты на задачах внутреннего заказчика типа "написать класс" или даже "добавить в класс метод, который делает ..."

Если разобраться в ситуации, то новому бизнесу важно выкатить минимально рабочую версию и заработать денег. Цель — заработать денег. На заработанные деньги бизнес сможет нанять QA и либо зафиксировать "успешный вариант решения задачи", либо переписать с нуля "успешный вариант решения задачи".
Поэтому тесты безусловно важны и полезны, но когда есть деньги на прожить до завтра (когда есть решение задачи на которое есть спрос). Поэтому в каком то смысле, я поддерживаю сторону заказчика — он понимает что первично, а что вторично. И… программист должен уметь тестировать то что он пишет (если через тесты — ок). QA нанимают уже потом, для оптимизации работы программиста и делегирования понятных задач.

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

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

Всякий, кто упускает важные детали и особенности работы с (микро)сервисной архитектурой обречен на страдания, нытьё по профильным ресурсам, дедлайны в кровавых соплях и, вероятно, потерю клиента в будущем (после аудита проекта грамотным специалистом, например).
Любопытную аналогию нам даёт микроэлектроника, где переход на микросервисы (ИС) в 70-е на текущий момент привёл к появлению невообразимых по сложности монолитов CPU/GPU.
Внезапно выяснилось, что скорость доступа достаточно критичный параметр :)
И дальше будет ещё веселее: интеграция памяти и процессора в одном чипе.

Почему дальше? Это давно уже случилось - кеш память процессора. А фишка в том что скорость этой памяти уж очень связана с ее стоимостью, чем быстрей тем дороже. Стоила бы как обычная DDR, ее давно бы уж гигабайтами в кристалл пихали, технической сложности в этом нет. Но если обычную DDR4-5 внедрить в кристалл, быстрей ни она ни скорость доступа от этого не станет, а вот удобство выбирать обьем устанавливаемой памяти увы изчезнет.

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

Посмотрите на смартфоны. Вы покупаете готовую конфигурацию. Если перестала устраивать — покупаете новую.

Так компы тем и хороши, в отличии от телефонов, что можно сменить конфигурацию, добавить памяти, сменить проц, видеркарту, при минимальных издержках, не меняя всю систему, а вы предлагает сделать из него неразборный моноблок? А чтоб добавить 8-16 Гб памяти нужно менять процессор? А зачем если текущего еще на 10 лет хватит, а вот требования софта к памяти растут. Да и представляете какое море вариантов будет, это не выгодно ни производителю ни потребителю? Сколько линеек CPU сейчас, многие десятки, а каждый будет еще с разным вариантом встроенной памяти (4-8-16-32-64-128 Гб) жуть берет.

Плюс еще, телефоны используются практически однотипно. Звонки, котики, ютуб, навигатор. На них не гоняют ML и не чертят самолеты, они не выступают серверами СУБД или виртуальными машинами. Поэтому достаточно некоей усредненной конфигурации. А использование ПК отличается настолько противоположными сценариями, что на одной и той же конфигурации (чипсет + процессор) где то нужно 128 Гб памяти и хватит 1Тб диска, а где то хватает 16 Гб , но нужно 10Пт диск + 100Гб/с net.

У большинства ПК тоже задачи совершенно типовые, вы же о серверных задачах пишете.

И FPGA, где вся плата зачастую выглядит как просто кусок текстолита, чтобы припаять ПЛИС и вывести её 900+ ножек наружу.
Да, точно! Про ПЛИСы хотел написать, но как-то вылетело из головы :) Эдакий аналог скриптов.
UFO just landed and posted this here
Большинство проектов (по моему опыту, может я просто неудачник) никогда не доживают до стадии, когда проявляются недостатки монолита. Но заранее в этом признаваться никто не хочет, поэтому сразу проектируют с размахом. Чтоб на тыщщу запросов в секунду и миллион пользователей как минимум, иначе смысл вообще затевать все это дело.
Смотря какие недостатки. Ограниченность или дороговизна масштабирования монолита — да, редкие. Отсутствие недостаточной изоляции модулей друг от друга, часто при первом же изменении требований вылазят, а то и раньше.
Логически отдельные части системы и должны быть разделены, но не обязательно на уровне сервисов, это могут быть просто отдельные библиотеки. И, как было указано в статье, проблемой часто является производительность базы данных. Т.е. разделить монолит на сервизы, которые будут работать с той же базой это не решение. Решение это переход, когда это возможно, на NoSQL базы, где скорость сохранения/чтения данных на порядки больше.
Есть мнение что проблемы с БД не в том, что традиционные БД работают недостаточно быстро. То есть, конечно, специализированные системы управления данными превосходят по производительности системы общего назначения (это не только баз данных касается), вот только область применения специализированных решений «немного» поуже. И быстродействие — характеристика, безусловно, важная, но далеко не единственная.

Да, NoSQL быстрее только в некоторых моментах. И тут нужно учесть что любая БД это данные которые где? правильно где то, но не в процессоре (на каком то гипотетическом носителе, RAM, SSD, HDD etc), и это на самом деле на 100% ограничивает скорость сохранения/чтения, быстрей которой физически ну никак, хоть 1000 ядер CPU используй. Далее транзакционность (она же consistency), практически в 99% NoSQL базах она отсутствует, т.к. там нет понятия транзакций в том смысле в каком оно есть в классических БД. А вот обеспечение этого механизма транзакций и сьедает ту скорость которой хвалятся весь парк "быстрых" БД.

И что лучше в итоге скорость обработки данных, в результате можем получить несогласованные (кривые) данные или все таки гарантированное качество данных при меньшей скорости (хотя тут зависит от понимания тонкостей работы конкретной БД и часто применение правильной архитектуры хранения нивелирует скорость самой СУБД)? Часто тут выбирает сам разработчик и часто не ту сторону. В прототипе с 10-100-1000 данными (утрированно) и парой коннектов с тестовых стендов все норм работает и быстро, но при уходе в прод и росте одновременных коннектов и обьеме данных оказывается что один затирает данные другого, половина сессий при одном запросе отдают одни данные, другие другие данные, третьи отваливаются и т.д. потому что в процессе выборки уже данные изменились, часть удалили, а без учета транзакций нет блокировок на данные, что и обуславливает такую скорость.

P.S. Приходит девушка устраиваться на работу секретаршей. Шеф спрашивает " Ас какой скоростью вы можете печатать на машинке? "Девушка " Ну... 1000-1200 знаков в минуту.... " Шеф: " Разве можно стакой скоростью печатать?!! " Девушка: " Печатать-то можно, но такаяхерня получается!!!! "

UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here

А нахамить хаму — это типа как-бы и не хамство вовсе?

UFO just landed and posted this here

Видите ли, когда хамите Вы — это, в первую очередь, касается непосредственно Вас самих (т.е. наносит ущерб Вам). Ущерб этот может проявляться по-разному, начиная от того, что морально не каждому комфортно чувствовать себя хамом (пусть даже и вынужденно/в ответ), и заканчивая тем, что свидетелем Вашего "ответного" хамства может стать другой человек, которые не в курсе предыстории и того, что это "ответное" хамство, и поэтому посчитает хамом именно Вас. Ну и плюс это создаёт очередной порочный круг — кому-то безосновательно показалось, что ему нахамили, он нахамил в ответ, ему следом нахамили уже вполне основательно… кому от этого стало лучше и когда этот круг прервётся?


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


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

UFO just landed and posted this here

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

Scalaz уже давно не в хайпе (разве что у них есть машина времени и scalaz 8 :)
Мы даже наблюдали несколько миграций от микросервисов обратно к монолиту.
segment.com/blog/goodbye-microservices

Прочитал. В статье рассказ о том как кто-то сделал микросервисы изначально неправильно, потом вернулся обратно к монолиту.

Проблемы которые там были:

  • Shared библиотеки у N микросервисов — это сразу индикатор что что-то делается не так. Вместо библиотек должны были быть тоже сервисы. Возможно должно было быть N микросервисов, которые не занимаются вводом выводом (запросами) а просто конвертируют из одного формата в другой. И один сервис который занимается вводом-выводом
  • N микросервисов имеют похожий код, который занимается одним и тем же. Точно что-то не так.
  • В какой-то момент у них был один общий репо на N сервисов, с пересекающимися тестами — теряется суть микросервисов. Они это исправили, но удивительно, что они сразу это не поняли


И эти люди даже ретроспективно не смогли понять что они сделали не так, и обвинили во всём микросервисы. Стыд и позор.
Возможно должно было быть N микросервисов, которые не занимаются вводом выводом (запросами) а просто конвертируют из одного формата в другой

Неужели накладные расходы на передачу данных окупают использование микросервисов?

Применительно к кейзу, который мы обсуждаем — они никаких реальных проблем не несут. Так что если микросервисы в этом проекте решали хоть какую-то реальную организационную или техническую проблему, которая есть в монолите, то несущественные расходы на передачу данных окупились бы.
У меня смешанные чувства. С одной стороны, микросервисы обещали вечную job security для сисадминов — ибо починить ЭТО теперь можно только обладая колоссальным опытом и выдержкой.

С другой стороны… Может, да ну его, такую job security? Это как у сантехников при работах по повышенному тарифу — денег больше, но уж изго… ешься в процессе по самое немогу.
Если речь про немецких сантехников — там часто бывает, что после ремонта дополнительная работа появляется, не указанная в заявке. Я видел… пару раз…

Писать микросервисы имеет смысл, когда:


  • Это действительно сервисы, а не попытка сделать модули, которые вызываются через HTTP
  • Есть несколько готовых микросервисов, которые можно использовать в проекте
  • Функционал приложения предполагает, что разработанные микросервисы можно будет переиспользовать в дальнейшем
  • Есть требования по поддержке предыдущих версий АПИ — запустить инстанс микросервиса, собранный из определенной ревизии проще, чем поддерживать несколько версий в исходниках (тут, конечно, остается вопрос версионирования базы, но он будет решаться и так, и так).
Главное, по-моему: требование независимого масштабирования модулей и(или) их разработки.
Иногда кажется что это мода такая сейчас и если не делать микросервисы — тебя засмеют и покроют позором…
Добавление и запуск кода, по крайней мере, для начальной среды, делается в первый же день. Но если мы отважились на микросервисы, время первоначального запуска взлетает до небес.

В одном из моих проектов, на микросервисной архитектуре, каждый микросервис можно обновить нагорячую без остановки работы, и это занимает секунды.
Разворачивание всей системы с нуля (порядка 80 сервисов) занимает 5-10 минут, соответственно апдейт всей системы занимает примерно такое же время.
А микросервисы были задолго до докера, и вариантов архитектуры с ними огромное количество.
Речь не про запуск инстансов. Речь про начало микросервисного проекта с нуля, с пустого репозитория(ев) и голых серверов (или аккаунта какого-то облака типа амазона)
Если сравнить монолит и микросервисы в этом плане, то отличий по временным затратам не будет. Мы же не разрабатываем все слои с нуля в бизнес-разработке, а выбираем платформу/фреймворк/язык и собираем приложение. По скорости получается примерно одинаково.
Если взять .net, то и монолит и микросервисы в решении будут представлены набором проектов, и на этапе именно разработки отличий особо не будет.
Более того, если работа командная, то разработка на микросервисном подходе может существенно ускорить дело, правка-ревью-тест-деплой микросервиса гораздо более громоздкое дело чем одного небольшого сервиса, который может быть независим.

P.S. сам я за гибридный подход, есть задачи где микросервисы удобнее, есть где монолит, а есть где и то и то в смеси.
Для монолитов системы автоматической сборки и деплоя, оркестрации инстансов и т.п. в продакшен, тест и дев контурах опциональны. А для MSA они, как говорится, маст хэв. А их настройка требует времени квалифицированного в этих делах специалиста.

А я сам больше за гибридный подход, где сначала пишется монолит, но с оглядкой на то, что отдельные модули нужно будет быстро выделить в микросервис, причём это должен суметь сделать человек, особо в модуле не разбирающийся. А может и не человек, а скрипт :)
Проблема в том что люди которые не читают первоисточники, и о новых технологиях судят по хайповым статьям на Хабре(и других ресурсах) не интересуются ни тем, какие проблемы решает новая технология, ни тем, какие у неё недостатки.
Микросервисы это отличная штука чтобы как можно быстрее доставлять фичи на прод в условиях когда много команд работают над различными функциональными частями продукта. Но для этого нужно чтобы на проекте были грамотные люди которые умеют разделять проект на разные функциональные части. У них высока стоимость ошибок декомпозиции и это сложнее чем монолит.
В современном мире же нередка ситуация когда команда программистов не смогла грамотно спроектировать монолит, наделав кучу архитектурных ошибок и подняв до небес стоимость поддержки этого проекта, и, путая причино-следственную связь, думая что микросервисы помогут им произвести грамотную декомпозицию системы убеждают бизнес выделить деньги на переписывание проекта на микросервисы.
А когда и это к успеху не приведет, получится по заветам Уди:
— Микросервисы не решили проблему декомпозиции, для декомпозиции нужны Экторы! Будем писать на Эрланге.
— …
— Экторы тоже не помогли декомпозировать систему. Нужно писать на F#
— Почему F#? Нуу… F# я ещё не пробовал, а это неплохая ачивка для резюме (с) ютуб
для этого нужно чтобы на проекте были грамотные люди которые умеют разделять проект на разные функциональные части


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

Это база, но её недостаточно. Как минимум ещё необходимо аккуратно проектировать API (чтобы гарантировать low coupling между сервисами, обеспечивать совместимость при развитии API, избегать сильных потерь производительности, упростить использование этого API на стороне клиента, уменьшить вероятность неявных ошибок на стороне клиента при использовании API) плюс учитывать особенности работы с данными из-за наличия у микросервисов собственных БД (как обеспечить целостность данных между разными БД, по возможности обходиться без распределённых транзакций, передавать данные асинхронно через всякие очереди, избегать лишних запросов данных из других сервисов) — внутри монолита, даже при корректном применении SRP и bounded context, все эти особенности работы с API и БД намного менее критичны и прощают намного больше ошибок, чем в случае микросервисов.

Ну проектирование и поддерживание API отдельный навык, как по мне. Особо не коррелирующий с разрезом монолит/SOA/MSA.
Ну… Литература по архитектуре приложений. Уже сказали про SRP и bounded context, читать про SOA и связанные темы, всё те же Фаулер, Дядя Боб, Уди Дахан. Вобщем, тут важнее бэкграунд в принципе по дизайну приложений.
Мой посыл в том что высокий coupling в монолите это плохо, но разделить проект на микросервисы оставив coupling это ещё в разы больнее. В идеале каждый сервис это отдельное приложение с отдельной базой данных, и данные из него не растекаются по другим сервисам.
В докладе по ссылке на Ютуб что я выше кинул комментарием выше как раз рассматриваются примеры таких проблем когда ну вот прям кажется, что задачи бизнеса требуют сосредоточения данных из различных контекстов в одном сервисе, и как этого не допустить.

И ещё раз — Микросервисы это штука которая позволяет в проекте(монолите) который уже разбит на контексты и функциональные части ещё эффективнее разделить команды, и ускорить доставку фич на прод путем устранения блокировок между командами, расплачиваясь за это как раз таки возрастающей сложностью проекта в целом и оверхедом на поддержку инфраструктуры.

Вот ещё классный доклад про контексты — www.youtube.com/watch?v=ez9GWESKG4I
Спасибо за рекомендацию литературы.
Но, хочу отметить, что «дизайн приложений» — это построение архитектуры приложения «с нуля» так сказать. А вот разделить готовое приложение на разные функциональные части задача несколько другая. Поэтому и навыки для ее решения должны быть другими. (Учитывая, например, замечание по поводу того, что каждый микросервис имеет, или может иметь, собственную БД.) Какие же это навыки?
Здесь скорее нужно сочетание аналитика (системного или прикладного?) и архитектора. Но остается вопрос API. Специалист какого профиля разрабатывает API?
Подскажите, пожалуйста, кто знает.
Готовое приложение уже должно быть разделено на функциональные части, имеющих собственные API. При принятии решения выделять их на микросервисы остаётся только их выделить технически. Если же не так, то сначала надо провести рефакторинг. И может оказаться, что и микросервисы не нужны :) Лучшая тут, по-моему, «Working Effectively with Legacy Code», Michael Feathers (Эффективная работа с унаследованным кодом).

А API в широком смысле слова разрабатывает большинство программистов, по-моему. Просто нужно будет использовать вместо внутрипроцессного взаимодействие межпроцессное (чаще всего сетевое).

Каких-то особых навыков я не могу припомнить. Разве что человек никогда не проектировал приложения в принципе, никогда не занимался межпроцессным взаимодействием, никогда не проводил рефакторинг, никогда не интегрировалася со сторонними сервисами. Да, есть нюансы, типа увеличившегося количества сетевых взаимодействий и, как результат, практическое увеличение количества ситуаций, когда что-то может пойти не так без готовых привычных средств обработки таких ситуаций типа транзакций в SQL СУБД или особой полезности использования асинхронных вызовов. Но если у вас есть опыт разработки распределенных приложений (прежде всего клиент-серверных) нужного масштаба с нуля, желательно с использованием асинхронных вызовов, есть опыт интеграции сторонних удалённых сервисов, если есть навыки рефакторинга, то сложно сказать почему вас нельзя подпускать к выделению микросервиса из монолита :)

Я вижу несколько основных задач, которые можно решить элегантно с помощью микросервисов:
  • Административная
    Раздельные циклы разработки, тестирование и конечно же деплоя
  • Технологическая независимость
    Можно выбирать инструмент под задачу. Тут заюзаем Go с хранением в памяти тут оставим java с полноценной субд. Гораздо легче внедрить новый инструмент.
  • Оптимизационная
    Можно гораздо гибче масштабировать приложение, точечено балансируя число интсансов сервисов, которые не вывозят нагрузку.
  • Дисциплинарно-архитектурная
    Когда для обращения к сервису нам нужно делать сетевой запрос, волей неволей начинаешь больше задумываться о разделении ответственной в приложении и локальности данных, чем когда можешь практически бесплатно залезть в БД или дернуть метод соседнего пакета

Но проблемы эти решаются, лишь в том случае, если есть желание и понимание того что и как нужно решать. Т.к с дополнительными возможностями микросервисы несут в себе нехилый оверхед. Т.е хорошее монолитное приложение из которого нужные части были вынесены как микросервисы — это круто. А вот если мы имеем дело с типичным гавнокодом, то в нем гораздо проще копаться(и меньше шансов положить всю систему) в случае монолита, чем в случае с архитектурой в стиле «микросервисы ради микросевисов»
тут заюзаем Go с хранением в памяти тут оставим java с полноценной субд. Гораздо легче внедрить новый инструмент
— в большом проэкте важно не расширять скоп технологий, т.к. потом трудно поддерживать код на разных технологиях.
это в маленьком проекте желательно не расширять стек технологий, потому что поддерживать его скорее всего будет 1-2 прогера… а вот в большом — велика вероятность, что один из 10-20 разрабов знает Go, python или assembler. И если на Go задача решается быстрее и эффективней — надо писать на Go, а не на PHP 5.4 (потому что у нас команда только его знает)
Вобщем, всё сводится к вопросу — «Кто будет чинить если эта фигня на проде упадёт?», если это достаточно серьёзный/важный/крупный кусок системы чтобы быть уверенным что на проекте будут люди для его поддержки — никаких проблем
С одной стороны, да, нужно быть уверенным. С другой, если ты единственный программист на проекте, то как можно быть уверенным хоть в чём-то?
UFO just landed and posted this here
Нужно исходить из задачи и возможностей, а не биться за чистоту подхода. Например sandbox в микросервисах часто бывает большим плюсом. Да и гетерогенная среда важна. Но это всё повышает требования к команде.

Настолько поверхностная статья, что даже грустно :(
Для чего выкладывать подобные переводы?
Чувак из оригинальной статьи близко не архитектор. Он всю жизнь занимается херокой и пгшечкой и мы хотим такого слушать? Быстро шагайте к Мартину дядьке Фаулеру и читайте.
Хехе, всего в паре комментов упомянут ответ на вопрос, а что же драйвит рост микросервисов.
Драйвит все, как обычно в этом материальном мире, бизнес.
Бизнес хочет, в условиях когда разработчиков несколько десятков(сотен, тысяч) релизиться чаще чем раз в месяц, при этом развивать бизнес в нескольких направлениях, при этом тренды по нагрузке плохо прогнозируемы, при этом сам бизнес плохо прогнозируем (седня у тебя маржа 50%, через год 10%, потому что активизировались конкуренты/законы поменялись/прочее).

Уже давно получен ответ, как это сделать — каждое направление бизнеса развивает отдельная команда. И у команды максимум полномочий и ответственности. И команды максимально независимы. Agile, привет.

Из независимости команд проистекает и необходимость (микро)сервисов — ровно одна команда (5-7человек) отвечает за сервис. Только она чинит в нем (в сервисе) баги и обеспечивает его работоспособность. И только она вкладывается в его (сервиса) развитие.

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

Да и в целом все ИТ-шные способы классификации сервисов на монолит и микросервис — это ИТ-шные развлечения. У бизнеса критерий простой. При прочих равных условиях, подход «один сервис — одна команда» в долгую выигрывает. Поэтому для бизнеса, монолит — это когда 2 и более команд активно пилят один сервис. Микросервис — когда сервис пилится только одной командой.

Понятно что и тут есть нюансы, типа есть СервисА, которые пилится командой А. СервисА активно юзает ЛибуБ и ЛибуЦ, от команд Б и Ц соответственно. Можно ли утверждать что сервис А зависит только от команды А? Запросто может быть что команды Б и Ц регулярно вносят возмущения в работу СервисаА. Если бизнесу важно, чтобы Б и Ц меньше вносили возмущений в работу СервисаА, то потребуется редизайн взаимодействия функциональности СервисаА, ЛибыБ, ЛибыЦ. Если неважно, останется как есть.
Если команды Б и Ц пилят не либы, а микросервисы, они точно так же мешают команде А. Возможно, даже сильнее. Потому что если либе нужно хранить какое-то новое состояние на стороне клиента (т.е. это уже не чистая либа, а модуль), то в монолите это как два байта переслать, а в микросервисной архитектуре нужно возиться с сессиями и тому подобным.
В целом, да. Просто разные подходы дают решение разных проблем.
И вообще, правильное деление на компоненты, это не про микросервисы и либы, а про правильное разделение ответственности и обработку ошибок.
Sign up to leave a comment.

Articles