Установка: от базовой химии к квантовой механике
Настройка базовой БД и приложения с фоновым процессом была довольно чётким процессом. Я публикую readme на Github — и часто через один час, максимум, парочку часов, всё работает, а я начинаю новый проект. Добавление и запуск кода, по крайней мере, для начальной среды, делается в первый же день. Но если мы отважились на микросервисы, время первоначального запуска взлетает до небес. Да, сейчас у нас есть Docker с оркестровкой и кластер машин K8, но для начинающего программиста всё это на порядок сложнее. Для многих джуниоров это бремя, которое действительно является ненужной сложностью.
Систему непросто понять
На минутку остановимся на нашем джуниоре. С монолитными приложениями в случае возникновения ошибки её легко было отследить и сразу перейти к отладке. Теперь у нас есть служба, которая разговаривает с другой службой, которая ставит что-то в очередь на шине сообщений, которая обрабатывает другую службу — и тут возникает ошибка. Мы должны собрать воедино все эти части, чтобы в конечном итоге узнать, что служба А работает в версии 11, а служба Е уже ожидает версию 12. Это сильно отличается от моего стандартного консолидированного журнала: приходится использовать интерактивный терминал/отладчик, чтобы пройти через процесс шаг за шагом. Отладка и понимание по сути стали сложнее.
Если нельзя отладить, возможно, мы их протестируем
Непрерывная интеграция и непрерывная разработка в настоящее время становятся общим местом. Большинство новых приложений, которые я вижу, с каждым новым релизом автоматически создают и запускают тесты и требуют, чтобы тесты проходили и просматривались перед регистрацией. Это отличные процессы, от которых нельзя отказываться, они стали большим сдвигом для многих компаний. Но теперь, чтобы действительно проверить сервис, я должен поднять полную рабочую версию своего приложения. Помните того нового инженера с кластером K8 из 150 сервисов? Ну, теперь мы научим нашу систему CI, как поднять все эти системы для проверки что всё действительно работает. Вероятно, это слишком много усилий, поэтому мы просто изолированно протестируем каждую часть: я уверен, что наши спецификации достаточно хороши, API чисты, а отказ службы изолирован и не повлияет на других.
У всех компромиссов есть веская причина. Верно?
Есть много причин для перехода на микросервисы. Я видел, что это делают для большей гибкости, для масштабирования команд, для производительности, чтобы обеспечить лучшую устойчивость работы. Но в реальности мы вложили десятилетия в инструментарий и практики разработки монолитов, которые продолжают развиваться. Я работаю с профессионалами в разных технологиях. Обычно мы говорим о масштабировании, потому что они сталкиваются с лимитами одного узла базы данных Postgres. Большая часть разговоров посвящена масштабированию БД.
Но мне всегда интересно узнать об их архитектуре. На каком этапе перехода к микросервисам они находятся. Интересно наблюдать, как всё больше инженеров говорят, что они довольны своим монолитным приложением. Многим микросервисы принесут пользу, а выгоды перевесят ухабы на пути миграции. Но лично мне дайте, пожалуйста, моё монолитное приложение, место на пляже — и я совершенно счастлив.
Комментарии (95)
wtpltd
18.03.2019 10:06+1Любые новые технологии или методологии вначале вызывают вау-вау. Сейчас все перепишем и будет счастье.
Потом приходит практика, реальные проекты, понимание достоинств, недостатков и границ применимости.
Поэтому, я так думаю, время «однозначных» статей за микросервисы прошло. Уже достаточно информации, чтобы осознанно принимать решения о том, как строить свою систему. Или перестраивать.adictive_max
18.03.2019 10:46А может просто не стоит всё так однозначно делить? Можно, например, посмотреть на процессоры, и взять на вооружение архитектурный принцип big.LITTLE, большое ядро для базовой логики и микросервисы для расширенной.
aPiks
18.03.2019 17:50big.LITTLE это принцип кластеризации. То есть мощные ядра поместить в один кластер, который работает под большой нагрузкой, а энерго-эффективные ядра для простых задач закинуть в другой кластер. Перенося эту архитектуру, вы получите 4 монолита и 4 микросервиса, с балансировщиками нагрузки для каждого кластера. Только смысла в такой архитектуре нет. Каждый микросервис будет копией остальных 4х. Это избыточно.
На самом деле, в современной разработке с облачными технологиями всё чаще применяется serverless архитектура. Как по мне — это хорошая альтернатива микросервисам.adictive_max
19.03.2019 04:26serverless архитектура. Как по мне — это хорошая альтернатива микросервисам.
Но ведь то, что маркетологи называют «serverless» — это в 90% случаев и есть крайний случай микросервисов, «по отдельному сервису на каждую функцию». Как он может быть им альтернативой?Ungla
19.03.2019 17:57Я когда первый раз прочитал serverless глазам своим не поверил. Как это код может работать без компьютера? Оказалось всё те же облака, которые всё те же серверы да к тому же внутри серверов контейнеры.
Piradius
18.03.2019 18:11А еще все новое изначально не настолько развито как старое и потому проигрывает. Со временем новая технология развивается и замещает старую. Отказываться от нового все-таки нельзя, но и внедрять в бой не глядя тоже глупо. Надо врубать мозг и осторожно, там, где от этого будет максимальная польза и минимальный возможный вред, пробовать.
menstenebris
18.03.2019 10:45+4Как-то так получилось что я уже на 3 месте работы переписываю микросервисы обратно на монолит. По какой то причине многим разработчикам кажется что, распределение сложных вычислений с большими объемами данных через микросервисы, связанные по api http или даже json-rpc через http, это нормальная идея. В итоге возвращение на монолитную конструкцию с многопоточностью обычно дает прирост производительности раз в 10.
В итоге я пришел к очень простому выводу. Микросервисная архитектура она не проще монолитной — она сложнее. В начале научитесь делать монолиты, а потом уже беритесь за микросервисы если они нужны. В противном случае вместо гибких микросервисов получается «копролит», эдакий плохо спроектированный монолит только с вызовами функций по сети.
exception13x
18.03.2019 10:54Почему никто не вспоминает о джуниорах когда наворачивают по 5 слоев абстракции?
menstenebris
18.03.2019 10:57Потому что мидлы которые наворачивают по 5 слоев абстракции думают что они сеньоры как минимум. Не пристало им думать о каких-то там джунах. К их божественному коду таких даже близко пускать нельзя.
Whuthering
18.03.2019 11:00+1Лучше уж 5 слоев абстракций, чем все плоское и намертво прибитое гвоздями, когда даже мельчайшее изменение требует раскапывание половины модуля, а в некоторых случаях и переписывание этой половины.
TonyLorencio
18.03.2019 11:04+1Вот только эти 5 слоев абстракций не гарантируют того, что не придется раскапывать/переписывать половину модуля
lanseg
18.03.2019 14:41Сталкивался и с тем и с тем.
Много слоёв абстракции? Чтобы что-то добавить, или изменить, нужно поправить 5 строчек, но может уйти не один час, чтобы найти места, где надо поправить эти строчки.
Плоское и намертво прибитое гвоздями? Казалось бы, рефакторинг и Find&Replace, а на деле копаться примерно столько же, сколько и в первом случае.xitt
18.03.2019 16:01Разница в том, что вы правите 5 строчек, тестируете и работает везде. Плоское надо тестировать все.
Да! Лучше писать лучше, чем хуже! Но слои при этом не виноваты.exception13x
18.03.2019 16:38И не факт что работать с плоской архитектурой медленнее.
Пример из практики.
В клиенте перепутаны настройки, при выборе А выдает результат Б, при выборе Б выдает результат А. Казалось бы, найди да поправь. Но из увлечения бывших программистов уровнями абстракции человек, которому предложили это поправить сказал «нужна неделя, чтобы разобраться, как оно работает». При этом протестировать настройку на всех конфигурациях — день.
Londoner
19.03.2019 02:34Да, чтоб потом мельчайшее изменение требовало переписывания пяти слоёв вместо одного.
Piradius
18.03.2019 18:20+1Не думаю, что микросервисы чем-то особо выделяются от других «крутых» штук. Вы видели реализации «чистых архитектур» и «чистый код»? Там точно так же 5 слоев абстракций и джунам ничего не ясно и их нужно учить.
С другой стороны, задачи у сеньоров и мидлов не в том, чтобы писать код понятный джунам, а в том, чтобы это все приносило в конечном счете деньги и лучше больше, чем меньше. Архитектуры и подходы, понятные только профессионалам, разрабатываются, чтобы экономить время и деньги.
А джуны научатся. В этом их главная задача.
epishman
18.03.2019 11:45В монолите многие ошибки отлавливаются на этапе компиляции, а в микро-сервисах, я просто не в курсе, существует ли технология, которая проверит согласованность всех интерфейсов на этапе сборки, до тестирования и вместо тестирования?
VolCh
18.03.2019 11:48Есть. Генерация низкоуроввневой библиотеки клиента микросервиса в процессе сборки микросервиса.
vsespb
18.03.2019 15:32-1Не нужно согласовывать все интерфейсы и пытаться как-то их протестировать. Нужно научиться писать приложения без багов, в той парадигме что вместе тестироваться они не будут. Пишите хорошее API, полностью документируйте пограничные случаи и не ломайте совместимость. Тестирование своего же API вам в помощь.
goldrobot
18.03.2019 15:53Нужно научиться писать приложения без багов
Спасибо за правильный совет. Я вам премного благодарен, теперь все в моей жизни будет хорошо, а логи чисты от ошибок!
Aries_ua
18.03.2019 17:56-1Скажите, кто вас такому учит? Вот серьезно, кто?
Расскажу один случай из своей практики. Был лидом на одном проекте/стартапе. Проект был «запущен» до меня. Проблем в нем было вагон и маленькая тележка. После анализа был предложен план, что как улучшить/переписать итд. Далее почти дословно:
(Я — тим лид, З — заказчик он же менеджер)
Я: Так же в это время входят тесты, что бы протестировать и выявить потенциальные проблемы.
З: Какие на# тесты мы стартап и у меня нет бюджета на тесты.
Я: O_O
Прошло три месяца. За это время в команде трудилось два джуниора, два мидла и один сеньор (моем лице).
При первом тестировании фокус группой было выявлено 100500 багов. Думаю вы догадываетесь что сказал заказчик. Но я все же напишу.
«Мне сказали что вы классные девелоперы, а вы тупые дебилы! Вы не умеете писать код!». Надо ли добавлять, что с проекта я конечно же ушел.powerman
18.03.2019 22:04+1Уходить надо было сразу после первого диалога. Либо вообще не нужно было упоминать тесты — Вы же не упоминаете необходимость создавать новые файлы, запускать команды в консоли, подбирать нормальные имена переменным и методам, читать документацию… тесты ничем не отличаются, это не что-то опциональное для большинства проектов. Можно в начале работы уточнить у заказчика, является ли проект прототипом, который не планируется разрабатывать и использовать дольше пары месяцев — и если он скажет "нет, это не прототип", то надо просто ставить в уме галочку "пишем с тестами" и переходить к следующему вопросу.
sentyaev
18.03.2019 23:04Писать тесты и рефакторить код — работа программиста, про это не нужно спрашивать.
VolCh
19.03.2019 09:55Спорно. Зависит от компании, от так называемой должностной инструкции.
powerman
19.03.2019 11:07+2Тесты бывают разные. Должен ли программист писать автоматизированные black box тесты и тесты внешних интерфейсов (от приёмочных тестов API микросервиса или Selenium тестов веб-UI до сложных интеграционных или простых BDD тестов) — действительно, зависит от компании и должностной инструкции. Но unit-тесты писать должен именно программист, более того, именно тот, который написал тестируемый этими unit-тестами код.
VolCh
19.03.2019 11:38Это если в компании вообще требуются писать юнит-тесты. Плюс есть вариант, когда пишет юнит-тесты, тот, кто ставит техническую задачу, а задача программиста по сути — обеспечить прохождение этих тестов разумным способом.
powerman
19.03.2019 12:51На мой взгляд, необходимость писать юнит-тесты должна определяться самим программистом, а не политикой компании. Обычно должностная инструкция подразумевает от программиста, что написанный им код будет выполнять поставленную задачу с требуемым уровнем качества. Необходимость в юнит-тестах должна определяться в зависимости от сложности задачи, требуемого качества, требований к дальнейшей поддержке этого кода и квалификации программиста — поэтому решить нужны ли ему тесты (и в каком количестве) чтобы выполнить требования должностной инструкции может только сам программист.
Это если в компании вообще требуются писать юнит-тесты.
Запрет писать тесты в компании, которая разрабатывает что-то кроме прототипов со сроком жизни в пару месяцев — просто ещё один пример оторванных от реальности требований, которые только вредят компании. Да, компания имеет право выдвигать любые (в рамках закона) требования к сотрудникам, но сотрудники имеют ответное право пойти работать в компанию с более устраивающими их требованиями. Я лично в таких проектах, где нельзя писать тесты и нет CI/CD, принципиально не участвую.
Плюс есть вариант, когда пишет юнит-тесты, тот, кто ставит техническую задачу, а задача программиста по сути — обеспечить прохождение этих тестов разумным способом.
Возможно, Вы имели в виду BDD тесты (низкоуровневые приёмочные тесты для публичного API класса/пакета/библиотеки, технически реализованные или в традиционном для BDD стиле "на языке заказчика" или в стиле обычных юнит-тестов) — там это нормально. Но в случае юнит-тестов это практически нереально на практике — такое можно практиковать только в очень крайних случаях, например при обучении студентов.
Задача юнит-тестов подтвердить, что написанный программистом код работает именно так, как ожидает написавший этот код программист. Учитывая слово "ожидает" написание юнит-тестов другим программистом становится значительно менее эффективным, т.к. другому намного сложнее угадать "ожидания" первого. Учитывая слово "код" является нормальным писать юнит-тесты к любому коду, включая внутренние вспомогательные функции/методы, не являющиеся частью публичного API класса/пакета/библиотеки — конечно, с учётом того, что перебарщивать с тестированием внутренних подробностей реализации не стоит, иначе тесты станут слишком хрупкими и их поддержка станет слишком дорогим удовольствием.
В отличие от задачи юнит-тестов, задача BDD/приёмочных тестов — подтвердить что код делает то, что нужно заказчику. В теории ожидаемое программистом поведение кода должно соответствовать нуждам заказчика, но на практике это разные вещи, поэтому и тесты для них тоже разные. Опять же, в теории, должно быть достаточно BDD/приёмочных тестов, но они ограничены тестированием публичного API, чего не всегда хватает и/или слишком усложняет и/или слишком замедляет тесты, плюс далеко не всегда "что нужно заказчику" в принципе известно с необходимой для написания BDD-тестов детальностью.
VolCh
19.03.2019 17:29+1поэтому решить нужны ли ему тесты (и в каком количестве) чтобы выполнить требования должностной инструкции может только сам программист.
Решить, что нужно писать тесты, программист, конечно, может. Но вот, допустим, решить, что их можно закоммитить в общую ветку, не говоря о внедрении в CI/CD процессы, часто решает кто-то другой. Пускай даже peer-коллега, проводящий ревью. Другая крайность — формальные требования к уровню покрытию кода, когда программист должен писать юнить-тесты, если не на весь свой код, то на какой-то процент.
Но в случае юнит-тестов это практически нереально на практике — такое можно практиковать только в очень крайних случаях, например при обучении студентов.
Ну почему только при обучении студентов? Придумал архитектор API, написал тесты и отдал на реализацию.
Задача юнит-тестов подтвердить, что написанный программистом код работает именно так, как ожидает написавший этот код программист.
Не согласен. Задача юнит-тестов в данном контексте, подтвердить, что написанный программистом код работает именно так, как ожидает написавшие эти тесты программист.
написание юнит-тестов другим программистом становится значительно менее эффективным, т.к. другому намного сложнее угадать "ожидания" первого.
Как по мне, то ровно наоборот. Формализованные ожидания куда эффективней реализовывать, чем что-то переданное обычным текстом или вообще устно.
В отличие от задачи юнит-тестов, задача BDD/приёмочных тестов — подтвердить что код делает то, что нужно заказчику.
Можно рассматривать в этом смысле юнит-тесты как приёмочные тесты на задачах внутреннего заказчика типа "написать класс" или даже "добавить в класс метод, который делает ..."
fukkit
18.03.2019 11:47+2Сервисная архитектура шикарна для балансировки нагрузки и выделения функционала в отдельные проекты в целях уменьшения сложности или оптимизации разработки.
Размер сервиса, микро он или нет, должен быть прямым следствием выполняемой им выделенной задачи, а не самоцелью и отдельным значимым показателем.
Монолит удобен пока он всем удобен. Когда полная сборка начинает занимать существенное время, иногда часы(!), вполне оправданы и пляски с модульными тестами, и выделение функционала в подпроект-сервис.
В этот момент желательно не упустить тщательное документирование получившейся системы, порядок её сборки и деплоя, и, возможно, настроить автоматизацию этих этапов при помощи систем оркестрации.
Всякий, кто упускает важные детали и особенности работы с (микро)сервисной архитектурой обречен на страдания, нытьё по профильным ресурсам, дедлайны в кровавых соплях и, вероятно, потерю клиента в будущем (после аудита проекта грамотным специалистом, например).
ybalt
18.03.2019 13:49+1Монолит проще на начальном этапе и сложен на развитом уровне
Микросервисы сложны на начальном этапе, но проще потом, при дальнейшем развитии.
Оптимально — сперва монолит, но работающий в microservice-ready инфрастуктуре с последующим раскалыванием его на микросервисы при необходимости.JediPhilosopher
18.03.2019 18:24Большинство проектов (по моему опыту, может я просто неудачник) никогда не доживают до стадии, когда проявляются недостатки монолита. Но заранее в этом признаваться никто не хочет, поэтому сразу проектируют с размахом. Чтоб на тыщщу запросов в секунду и миллион пользователей как минимум, иначе смысл вообще затевать все это дело.
VolCh
18.03.2019 18:48Смотря какие недостатки. Ограниченность или дороговизна масштабирования монолита — да, редкие. Отсутствие недостаточной изоляции модулей друг от друга, часто при первом же изменении требований вылазят, а то и раньше.
Exponent
18.03.2019 14:01Логически отдельные части системы и должны быть разделены, но не обязательно на уровне сервисов, это могут быть просто отдельные библиотеки. И, как было указано в статье, проблемой часто является производительность базы данных. Т.е. разделить монолит на сервизы, которые будут работать с той же базой это не решение. Решение это переход, когда это возможно, на NoSQL базы, где скорость сохранения/чтения данных на порядки больше.
eefadeev
18.03.2019 16:21+1Есть мнение что проблемы с БД не в том, что традиционные БД работают недостаточно быстро. То есть, конечно, специализированные системы управления данными превосходят по производительности системы общего назначения (это не только баз данных касается), вот только область применения специализированных решений «немного» поуже. И быстродействие — характеристика, безусловно, важная, но далеко не единственная.
s-kozlov
18.03.2019 14:02На одном собеседовании мне описали гипотетическое веб-приложение и спросили, на какие микросервисы я бы его разбил. Я ответил, что ни на какие, т.к. пока нет понимания, как и зачем лучше разбить — это будет ясно во время эксплуатации. Мне не перезвонили. ИЧСХ, эти ребята пишут на Scala и юзают scalaz. Hype driven development, мать его.
VolodjaT
18.03.2019 14:41Правильно что не перезвонили
Так логично было спросить детали о системе (узкие места, проблемы итд)s-kozlov
19.03.2019 05:30Это гадание на кофейной гуще, а не определение узких мест.
И кстати: не перезванивать кандидату — это обыкновенное хамство (если, конечно, он не хамил сам).powerman
19.03.2019 11:08А нахамить хаму — это типа как-бы и не хамство вовсе?
s-kozlov
19.03.2019 12:52Нет, я считаю, что не перезвонить кандидату, который пришел и всем нахамил, — это не хамство.
powerman
19.03.2019 13:15Видите ли, когда хамите Вы — это, в первую очередь, касается непосредственно Вас самих (т.е. наносит ущерб Вам). Ущерб этот может проявляться по-разному, начиная от того, что морально не каждому комфортно чувствовать себя хамом (пусть даже и вынужденно/в ответ), и заканчивая тем, что свидетелем Вашего "ответного" хамства может стать другой человек, которые не в курсе предыстории и того, что это "ответное" хамство, и поэтому посчитает хамом именно Вас. Ну и плюс это создаёт очередной порочный круг — кому-то безосновательно показалось, что ему нахамили, он нахамил в ответ, ему следом нахамили уже вполне основательно… кому от этого стало лучше и когда этот круг прервётся?
Если Вы просто не хотите кому-то спускать хамство в свой адрес, то для этого есть менее разрушительные способы, чем нахамить в ответ. Например, если Вам позволяет уровень образованности/эрудиции, можно очень вежливо и тонко потроллить хама в ответ, так, что формально придраться не к чему, и менее образованный человек даже примет Ваши слова за чистую монету (и решит что он Вас "сделал" своим хамством), но любой более образованный сторонний наблюдатель отлично поймёт, что на самом деле всё совсем наоборот, а менее образованный сторонний наблюдатель просто решит, что Вы слишком вежливы, и он бы на Вашем месте не смог так сдерживаться (что всё ещё намного лучше, чем если он бы посчитал хамом Вас).
Если троллить нет возможности или желания, то можно просто свести дальнейшее общение с хамом к минимуму и сделать его максимально формальным — это защитит Вас от дальнейшего хамства с его стороны не вредя при этом Вам самому.
s-kozlov
20.03.2019 06:14Эк вы обобщили… Я ж только про «не перезвонить» говорил. Вот вы будете перезванивать кандидату, который пришел на собес в трусах и сказал «вы пидорасы, я — д'Артаньян, у вас тут все неправильно, работать у вас мне не хочется, но если предложите миллион рублей, то подумаю»? И если да, то зачем? А если нет, то разве это хамство?
powerman
20.03.2019 09:30Нет, я ему сразу на собесе скажу, что он для нас слишком хорош, и, возможно, в будущем, когда компания достаточно вырастет, мы с ним свяжемся.
Dveim
18.03.2019 20:06+1Scalaz уже давно не в хайпе (разве что у них есть машина времени и scalaz 8 :)
vsespb
18.03.2019 15:25-1Мы даже наблюдали несколько миграций от микросервисов обратно к монолиту.
segment.com/blog/goodbye-microservices
Прочитал. В статье рассказ о том как кто-то сделал микросервисы изначально неправильно, потом вернулся обратно к монолиту.
Проблемы которые там были:
- Shared библиотеки у N микросервисов — это сразу индикатор что что-то делается не так. Вместо библиотек должны были быть тоже сервисы. Возможно должно было быть N микросервисов, которые не занимаются вводом выводом (запросами) а просто конвертируют из одного формата в другой. И один сервис который занимается вводом-выводом
- N микросервисов имеют похожий код, который занимается одним и тем же. Точно что-то не так.
- В какой-то момент у них был один общий репо на N сервисов, с пересекающимися тестами — теряется суть микросервисов. Они это исправили, но удивительно, что они сразу это не поняли
И эти люди даже ретроспективно не смогли понять что они сделали не так, и обвинили во всём микросервисы. Стыд и позор.DistortNeo
18.03.2019 18:23Возможно должно было быть N микросервисов, которые не занимаются вводом выводом (запросами) а просто конвертируют из одного формата в другой
Неужели накладные расходы на передачу данных окупают использование микросервисов?
vsespb
18.03.2019 18:33+1Применительно к кейзу, который мы обсуждаем — они никаких реальных проблем не несут. Так что если микросервисы в этом проекте решали хоть какую-то реальную организационную или техническую проблему, которая есть в монолите, то несущественные расходы на передачу данных окупились бы.
amarao
18.03.2019 15:31У меня смешанные чувства. С одной стороны, микросервисы обещали вечную job security для сисадминов — ибо починить ЭТО теперь можно только обладая колоссальным опытом и выдержкой.
С другой стороны… Может, да ну его, такую job security? Это как у сантехников при работах по повышенному тарифу — денег больше, но уж изго… ешься в процессе по самое немогу.Oz_Alex
19.03.2019 06:14Если речь про немецких сантехников — там часто бывает, что после ремонта дополнительная работа появляется, не указанная в заявке. Я видел… пару раз…
indestructable
18.03.2019 16:30Писать микросервисы имеет смысл, когда:
- Это действительно сервисы, а не попытка сделать модули, которые вызываются через HTTP
- Есть несколько готовых микросервисов, которые можно использовать в проекте
- Функционал приложения предполагает, что разработанные микросервисы можно будет переиспользовать в дальнейшем
- Есть требования по поддержке предыдущих версий АПИ — запустить инстанс микросервиса, собранный из определенной ревизии проще, чем поддерживать несколько версий в исходниках (тут, конечно, остается вопрос версионирования базы, но он будет решаться и так, и так).
VolCh
18.03.2019 17:56Главное, по-моему: требование независимого масштабирования модулей и(или) их разработки.
santa324
18.03.2019 16:33Иногда кажется что это мода такая сейчас и если не делать микросервисы — тебя засмеют и покроют позором…
Ogoun
18.03.2019 16:46+1Добавление и запуск кода, по крайней мере, для начальной среды, делается в первый же день. Но если мы отважились на микросервисы, время первоначального запуска взлетает до небес.
В одном из моих проектов, на микросервисной архитектуре, каждый микросервис можно обновить нагорячую без остановки работы, и это занимает секунды.
Разворачивание всей системы с нуля (порядка 80 сервисов) занимает 5-10 минут, соответственно апдейт всей системы занимает примерно такое же время.
А микросервисы были задолго до докера, и вариантов архитектуры с ними огромное количество.VolCh
18.03.2019 17:58Речь не про запуск инстансов. Речь про начало микросервисного проекта с нуля, с пустого репозитория(ев) и голых серверов (или аккаунта какого-то облака типа амазона)
Ogoun
18.03.2019 19:35Если сравнить монолит и микросервисы в этом плане, то отличий по временным затратам не будет. Мы же не разрабатываем все слои с нуля в бизнес-разработке, а выбираем платформу/фреймворк/язык и собираем приложение. По скорости получается примерно одинаково.
Если взять .net, то и монолит и микросервисы в решении будут представлены набором проектов, и на этапе именно разработки отличий особо не будет.
Более того, если работа командная, то разработка на микросервисном подходе может существенно ускорить дело, правка-ревью-тест-деплой микросервиса гораздо более громоздкое дело чем одного небольшого сервиса, который может быть независим.
P.S. сам я за гибридный подход, есть задачи где микросервисы удобнее, есть где монолит, а есть где и то и то в смеси.VolCh
18.03.2019 20:07Для монолитов системы автоматической сборки и деплоя, оркестрации инстансов и т.п. в продакшен, тест и дев контурах опциональны. А для MSA они, как говорится, маст хэв. А их настройка требует времени квалифицированного в этих делах специалиста.
А я сам больше за гибридный подход, где сначала пишется монолит, но с оглядкой на то, что отдельные модули нужно будет быстро выделить в микросервис, причём это должен суметь сделать человек, особо в модуле не разбирающийся. А может и не человек, а скрипт :)
EvgeniiR
18.03.2019 16:51+3Проблема в том что люди которые не читают первоисточники, и о новых технологиях судят по хайповым статьям на Хабре(и других ресурсах) не интересуются ни тем, какие проблемы решает новая технология, ни тем, какие у неё недостатки.
Микросервисы это отличная штука чтобы как можно быстрее доставлять фичи на прод в условиях когда много команд работают над различными функциональными частями продукта. Но для этого нужно чтобы на проекте были грамотные люди которые умеют разделять проект на разные функциональные части. У них высока стоимость ошибок декомпозиции и это сложнее чем монолит.
В современном мире же нередка ситуация когда команда программистов не смогла грамотно спроектировать монолит, наделав кучу архитектурных ошибок и подняв до небес стоимость поддержки этого проекта, и, путая причино-следственную связь, думая что микросервисы помогут им произвести грамотную декомпозицию системы убеждают бизнес выделить деньги на переписывание проекта на микросервисы.
А когда и это к успеху не приведет, получится по заветам Уди:
— Микросервисы не решили проблему декомпозиции, для декомпозиции нужны Экторы! Будем писать на Эрланге.
— …
— Экторы тоже не помогли декомпозировать систему. Нужно писать на F#
— Почему F#? Нуу… F# я ещё не пробовал, а это неплохая ачивка для резюме (с) ютубlieh_tzu
19.03.2019 05:28для этого нужно чтобы на проекте были грамотные люди которые умеют разделять проект на разные функциональные части
Подскажите, пожалуйста, какими навыками и знаниями должны обладать такие люди? И где можно об этом почитать? Вопрос даже могу сформулировать более глобально: что и где почитать о методологии разделения монолитных процессов на микросервисы?VolCh
19.03.2019 07:59Обычный SRP по сути из ООП и выделение контекста из DDD.
powerman
19.03.2019 11:28Это база, но её недостаточно. Как минимум ещё необходимо аккуратно проектировать API (чтобы гарантировать low coupling между сервисами, обеспечивать совместимость при развитии API, избегать сильных потерь производительности, упростить использование этого API на стороне клиента, уменьшить вероятность неявных ошибок на стороне клиента при использовании API) плюс учитывать особенности работы с данными из-за наличия у микросервисов собственных БД (как обеспечить целостность данных между разными БД, по возможности обходиться без распределённых транзакций, передавать данные асинхронно через всякие очереди, избегать лишних запросов данных из других сервисов) — внутри монолита, даже при корректном применении SRP и bounded context, все эти особенности работы с API и БД намного менее критичны и прощают намного больше ошибок, чем в случае микросервисов.
VolCh
19.03.2019 11:47Ну проектирование и поддерживание API отдельный навык, как по мне. Особо не коррелирующий с разрезом монолит/SOA/MSA.
EvgeniiR
19.03.2019 12:16Ну… Литература по архитектуре приложений. Уже сказали про SRP и bounded context, читать про SOA и связанные темы, всё те же Фаулер, Дядя Боб, Уди Дахан. Вобщем, тут важнее бэкграунд в принципе по дизайну приложений.
Мой посыл в том что высокий coupling в монолите это плохо, но разделить проект на микросервисы оставив coupling это ещё в разы больнее. В идеале каждый сервис это отдельное приложение с отдельной базой данных, и данные из него не растекаются по другим сервисам.
В докладе по ссылке на Ютуб что я выше кинул комментарием выше как раз рассматриваются примеры таких проблем когда ну вот прям кажется, что задачи бизнеса требуют сосредоточения данных из различных контекстов в одном сервисе, и как этого не допустить.
И ещё раз — Микросервисы это штука которая позволяет в проекте(монолите) который уже разбит на контексты и функциональные части ещё эффективнее разделить команды, и ускорить доставку фич на прод путем устранения блокировок между командами, расплачиваясь за это как раз таки возрастающей сложностью проекта в целом и оверхедом на поддержку инфраструктуры.
Вот ещё классный доклад про контексты — www.youtube.com/watch?v=ez9GWESKG4Ilieh_tzu
19.03.2019 20:27Спасибо за рекомендацию литературы.
Но, хочу отметить, что «дизайн приложений» — это построение архитектуры приложения «с нуля» так сказать. А вот разделить готовое приложение на разные функциональные части задача несколько другая. Поэтому и навыки для ее решения должны быть другими. (Учитывая, например, замечание по поводу того, что каждый микросервис имеет, или может иметь, собственную БД.) Какие же это навыки?
Здесь скорее нужно сочетание аналитика (системного или прикладного?) и архитектора. Но остается вопрос API. Специалист какого профиля разрабатывает API?
Подскажите, пожалуйста, кто знает.VolCh
20.03.2019 07:14Готовое приложение уже должно быть разделено на функциональные части, имеющих собственные API. При принятии решения выделять их на микросервисы остаётся только их выделить технически. Если же не так, то сначала надо провести рефакторинг. И может оказаться, что и микросервисы не нужны :) Лучшая тут, по-моему, «Working Effectively with Legacy Code», Michael Feathers (Эффективная работа с унаследованным кодом).
А API в широком смысле слова разрабатывает большинство программистов, по-моему. Просто нужно будет использовать вместо внутрипроцессного взаимодействие межпроцессное (чаще всего сетевое).
Каких-то особых навыков я не могу припомнить. Разве что человек никогда не проектировал приложения в принципе, никогда не занимался межпроцессным взаимодействием, никогда не проводил рефакторинг, никогда не интегрировалася со сторонними сервисами. Да, есть нюансы, типа увеличившегося количества сетевых взаимодействий и, как результат, практическое увеличение количества ситуаций, когда что-то может пойти не так без готовых привычных средств обработки таких ситуаций типа транзакций в SQL СУБД или особой полезности использования асинхронных вызовов. Но если у вас есть опыт разработки распределенных приложений (прежде всего клиент-серверных) нужного масштаба с нуля, желательно с использованием асинхронных вызовов, есть опыт интеграции сторонних удалённых сервисов, если есть навыки рефакторинга, то сложно сказать почему вас нельзя подпускать к выделению микросервиса из монолита :)
arturpanteleev
18.03.2019 17:23+1Я вижу несколько основных задач, которые можно решить элегантно с помощью микросервисов:
- Административная
Раздельные циклы разработки, тестирование и конечно же деплоя - Технологическая независимость
Можно выбирать инструмент под задачу. Тут заюзаем Go с хранением в памяти тут оставим java с полноценной субд. Гораздо легче внедрить новый инструмент. - Оптимизационная
Можно гораздо гибче масштабировать приложение, точечено балансируя число интсансов сервисов, которые не вывозят нагрузку. - Дисциплинарно-архитектурная
Когда для обращения к сервису нам нужно делать сетевой запрос, волей неволей начинаешь больше задумываться о разделении ответственной в приложении и локальности данных, чем когда можешь практически бесплатно залезть в БД или дернуть метод соседнего пакета
Но проблемы эти решаются, лишь в том случае, если есть желание и понимание того что и как нужно решать. Т.к с дополнительными возможностями микросервисы несут в себе нехилый оверхед. Т.е хорошее монолитное приложение из которого нужные части были вынесены как микросервисы — это круто. А вот если мы имеем дело с типичным гавнокодом, то в нем гораздо проще копаться(и меньше шансов положить всю систему) в случае монолита, чем в случае с архитектурой в стиле «микросервисы ради микросевисов»Exponent
18.03.2019 17:47тут заюзаем Go с хранением в памяти тут оставим java с полноценной субд. Гораздо легче внедрить новый инструмент
— в большом проэкте важно не расширять скоп технологий, т.к. потом трудно поддерживать код на разных технологиях.Knightt
18.03.2019 21:16+1это в маленьком проекте желательно не расширять стек технологий, потому что поддерживать его скорее всего будет 1-2 прогера… а вот в большом — велика вероятность, что один из 10-20 разрабов знает Go, python или assembler. И если на Go задача решается быстрее и эффективней — надо писать на Go, а не на PHP 5.4 (потому что у нас команда только его знает)
EvgeniiR
18.03.2019 23:27Вобщем, всё сводится к вопросу — «Кто будет чинить если эта фигня на проде упадёт?», если это достаточно серьёзный/важный/крупный кусок системы чтобы быть уверенным что на проекте будут люди для его поддержки — никаких проблем
VolCh
19.03.2019 09:58С одной стороны, да, нужно быть уверенным. С другой, если ты единственный программист на проекте, то как можно быть уверенным хоть в чём-то?
- Административная
sotnikdv
18.03.2019 19:47+2Еще одна история, как нарушить рекоммендации и потом жаловаться на судьбу.
Да прочитайте вы хоть пару вводных статей, прежде чем начинать их использовать.
Микросервисы, как и SOA когда-то, решают проблему complexity, начиная с определённого масштаба, проблему экспоненциально растущего required effort to change, согласования релизных циклов и кучу чего еще. За счет оверхеда на управление сервисами.
Переход на микросервисную архитектуру выполняется, когда затраты на изменение монолита становятся больше, чем декомпозиция и поддержка микросервисов.
Нельзя начинать с микросервисов.
Нельзя начинать микросервисы без хорошей команды опсов и автоматизации.
Хайп, хайп… Пороть^W Учить надо таких архитекторов.
dmitriym09
19.03.2019 00:08Нужно исходить из задачи и возможностей, а не биться за чистоту подхода. Например sandbox в микросервисах часто бывает большим плюсом. Да и гетерогенная среда важна. Но это всё повышает требования к команде.
AlexJco
19.03.2019 09:53+1Для чего выкладывать подобные переводы?
Чувак из оригинальной статьи близко не архитектор. Он всю жизнь занимается херокой и пгшечкой и мы хотим такого слушать? Быстро шагайте к Мартину дядьке Фаулеру и читайте.
ggo
19.03.2019 10:43Хехе, всего в паре комментов упомянут ответ на вопрос, а что же драйвит рост микросервисов.
Драйвит все, как обычно в этом материальном мире, бизнес.
Бизнес хочет, в условиях когда разработчиков несколько десятков(сотен, тысяч) релизиться чаще чем раз в месяц, при этом развивать бизнес в нескольких направлениях, при этом тренды по нагрузке плохо прогнозируемы, при этом сам бизнес плохо прогнозируем (седня у тебя маржа 50%, через год 10%, потому что активизировались конкуренты/законы поменялись/прочее).
Уже давно получен ответ, как это сделать — каждое направление бизнеса развивает отдельная команда. И у команды максимум полномочий и ответственности. И команды максимально независимы. Agile, привет.
Из независимости команд проистекает и необходимость (микро)сервисов — ровно одна команда (5-7человек) отвечает за сервис. Только она чинит в нем (в сервисе) баги и обеспечивает его работоспособность. И только она вкладывается в его (сервиса) развитие.
Какие при этом используются технологии (нет никаких микросервисных технологий), каков размер кодовой базы (микро — это не от размера кодовой базы) — не имеет значения.vanxant
20.03.2019 14:09Только это может быть либа или компонента, а не микросервис. Никто не отменял нормальную архитектуру в монолите.
ggo
21.03.2019 07:27Да, запросто может быть либа. И вообще любой другой способ деления функциональных компонент.
Но потребность бизнеса в разумной независимости команд друг от друга остается во главе. Разумной — по эффективности.
Да и в целом все ИТ-шные способы классификации сервисов на монолит и микросервис — это ИТ-шные развлечения. У бизнеса критерий простой. При прочих равных условиях, подход «один сервис — одна команда» в долгую выигрывает. Поэтому для бизнеса, монолит — это когда 2 и более команд активно пилят один сервис. Микросервис — когда сервис пилится только одной командой.
Понятно что и тут есть нюансы, типа есть СервисА, которые пилится командой А. СервисА активно юзает ЛибуБ и ЛибуЦ, от команд Б и Ц соответственно. Можно ли утверждать что сервис А зависит только от команды А? Запросто может быть что команды Б и Ц регулярно вносят возмущения в работу СервисаА. Если бизнесу важно, чтобы Б и Ц меньше вносили возмущений в работу СервисаА, то потребуется редизайн взаимодействия функциональности СервисаА, ЛибыБ, ЛибыЦ. Если неважно, останется как есть.vanxant
21.03.2019 08:46Если команды Б и Ц пилят не либы, а микросервисы, они точно так же мешают команде А. Возможно, даже сильнее. Потому что если либе нужно хранить какое-то новое состояние на стороне клиента (т.е. это уже не чистая либа, а модуль), то в монолите это как два байта переслать, а в микросервисной архитектуре нужно возиться с сессиями и тому подобным.
ggo
21.03.2019 14:44+1В целом, да. Просто разные подходы дают решение разных проблем.
И вообще, правильное деление на компоненты, это не про микросервисы и либы, а про правильное разделение ответственности и обработку ошибок.
tuxi
Отрезаем кусочки от монолита и выносим в отдельный сервис, если выясняется, что аналогичная функциональность требуется более чем в одном месте системы «состоящей из 2..3-х монолитов». Размер «глыб» кардинально не уменьшается, но хотя бы не растет драматически. А вот в ситуации с одним монолитным приложением, уже не все так однозначно, поэтому полностью поддерживаю посыл в статье.
PS: Документировать кстати все равно надо, как и решать вопрос производительности (время доступа).