Статья посвящена анализу и сравнению двух моделей построения систем — монолитной и с разделением на микросервисы. В ней мы с разных сторон оценим оба этих подхода и связанную с ними сложность, убедившись в превосходстве последнего. Представим микросервисы и прочие архитектуры в реалистичном свете, не воскрешая то, что должно оставаться мёртвым.
Писатель ужасов Г. Ф. Лавкрафт в своём коротком произведении «Nameless ciry» приписал безумному вымышленному поэту эту ставшую известной цитату:
That is not dead which can eternal lie / And with strange aeons even death may die.
Если нечто может бездействовать вечно, не значит, что оно умерло / А в течение неопределённой вечности даже смерть может оказаться конечной
Да, здесь и сейчас я позволю себе отнести эту фразу к монолитам (и прочим явлениям), а не вымышленным богам, спящим в океане в предвкушении поглощения человечества.
Эта статья представляет размышления и по своей сути сугубо субъективна. Если вас интересует более технический, объективный подход к конкретным решениям и тематическим обсуждениям, то рекомендую обратить внимание на эти прекрасные книги:
- Fundamentals of Software Architecture: An Engineering Approach
- Software Architecture: The Hard Parts: Modern Trade-Off Analyses for Distributed Architectures
- Building Microservices: Designing Fine-Grained Systems
Определение: микросервисы не обязательно нужно приравнивать к Kubernetes. По крайней мере, для меня это совершенно другое. Более чистой реализацией микросервисов я нахожу архитектурный шаблон «функция как услуга» (FaaS, Function as a Service) хотя в этой статье термин «микросервис» нужно представлять как можно обобщённей.
Последняя оговорка: я не буду выступать против монолитов в тех случаях, где они рационально уместны, например, в очень ограниченных/небольших масштабах, прототипах, по причинам безопасности и в аналогичных контекстах. И хотя монолиты определённо могут выступать допустимым архитектурным стилем, нельзя пренебрегать анализом проблемы, которую ПО должно решать, атрибутами качества и пониманием области, в которой это ПО действует.
Проверка на соответствие действительности:
В прогрессе нет неизбежности.
Многие неудачные идеи часто возвращаются после того, как они были достаточно долго скрыты.
Одна из таких идей – монолиты. Как и любая другая идея, даже они с определённой позиции нужны. И я хочу, чтобы вы поняли меня правильно. Существуют совершенно рациональные причины для их ситуативного использования – тем не менее здесь я буду рассуждать о том, что считаю основной проблемой:
Проблема монолитов значительно шире чисто технической стороны (то есть одной развёртываемой единицы) и становится следствием отсутствия логического разделения задачи, ведущего ко вторичным проблемам, таким как неудачное определение масштабов работ и сложности с коммуникацией.
Как мы умудрились оказаться в такой ситуации?
▍ Синтаксические оковы и золотые молотки
Представьте себе человека, только что окончившего колледж, какую-то программу или даже просто самоучку, который теперь готов начать работать с ПО «профессионально», что бы это не означало в современном мире. Он знает весь синтаксис одного или нескольких языков. Но может ли он проектировать? Скорее всего, нет. Знания синтаксиса недостаточно для создания ПО.
Если я запихну весь код в ящик, окажется ли это правильным в любом случае?
Архитекторы-строители могут жаловаться, что большинство начинающих ознакомляются с чертежами строительства недостаточно тщательно, что ведёт к медленной цепочке обратной связи и замедляет освоение профессии. Разрезание ленточки при запуске дома – это роскошь, которую могут себе позволить немногие и не очень часто.
И я по факту не сильно верю в архитекторов ПО (как в должность) – их даже нет во многих крупных технологических компаниях – но я твёрдо верю в архитектуру ПО и его проектирование.
Хотя искусство проектирования ПО уже утрачено, даже в эпоху, когда мы начали создавать программные продукты невероятно быстро.
ПО не ограничено физикой подобно зданиям. Оно ограничивается лишь воображением, проектом и организацией. Если коротко, то оно ограничивается возможностями людей, а не возможностями мира. «Мы встретились с врагом, которым оказались мы сами». — Мартин Фаулер, «Who Needs an Architect?»
ПО является результатом социо-технических процессов. Оно не создаётся в ходе одного только программирования. Здесь можно вспомнить закон Конвея и то, как:
«любая организация, проектируя систему (определяемую в широком смысле), будет создавать дизайн, структура которого будет копировать структуру коммуникации внутри этой организации».
Было бы легко провести здесь некую параллель с микросервисами. Что, если проблема не в технологии? Лично для меня абсолютно логично утверждение, что многие организации и люди, решительно отвергающие микросервисы, никогда не оказывались в успешных условиях. Я считаю, что в подобных организациях зачастую наблюдаются тенденции к научному менеджменту (тейлоризму), «линейно-функциональной организации» и созданию не до конца соответствующих стандарту продуктов. Всё это по причине отсутствия диалога с потребителем, использования «метрик тщеславия» и принятия решений на основе мнений самых высокооплачиваемых сотрудников. Звучит грубо и несправедливо? Так всё было устроено в большинстве компаний, где мне довелось работать, и о которых я слышал.
Испытывая боль, дискомфорт и неудачи мы, как это характерно для людей в целом стремимся замкнуться, замереть, смиряемся и прочими способами закрепляем те модели поведения, которые нас к этому ведут. Мы будто отказываемся от тех же убеждений и знаний, которые в противном случае используем. И здесь раздаются обезумевшие крики: «Всё это из-за микросервисов, верните мой золотой молоток!»
Учитывая, что «мы не можем решить проблемы, используя ту же модель мышления, с помощью которой их создали»—утверждение, которое принадлежит, возможно, Альберту Эйнштейну – не будет ли полностью адекватным ответом на сложность микросервисов, облачных структур и всему этому ажиотажу возвращение к чему-то «простому», что «работало»? Так что давайте подумаем о том, почему монолиты могут быть столь привлекательной идеей (или протоптанной тропой) в современном мире ПО.
▍ Нет, монолит всё равно не решение
Камиль Гржибека написал прекрасную статью по теме модульных монолитов. Но я хочу оспорить идею о том, что для этого необходим монолит – монолит лишь добавляет боль в принципы построения структуры и декомпозиции, которые в ином случае работают очень хорошо. На деле вы также можете встроить черты подобной архитектуры в конфигурацию по шаблону «функция как услуга». Из важных общих моментов в наших с Камилем подходах можно выделить то, что с помощью продуманной программной архитектуры (то есть модулей) можно разделить систему на хорошие логические элементы, и его проект на основе DDD (Domain Driven Design, предметно-ориентированное проектирование) хороший тому пример. Это здорово.
Следовательно: если вы ненавидите микросервисы, то упускаете суть.
Микросервисы не обязательно должны означать, что каждая Лямбда (или любая FaaS, которая придёт вам на ум) является полностью самодостаточной, свободно движущейся платонической вселенной без сложных модульных/ориентированных на классы взаимодействий – мой DDD-проект Get-a-Room и моя онлайн-книга по DDD показывают насколько. И они не развёртываются принудительно в космосе как спутники – они являются частью некоего контекста, обычно сервиса, с его собственными интерфейсами.
Если реализовать это разумно и аккуратно (как указано в ссылках), вы получите независимую возможность развёртывания, меньшую поверхность ошибок и более точное инфраструктурное отражение вашей системы, не прибегая к монолитной реализации – то, что Камиль правомерно называет единственным истинным свойством «монолитных» систем.
И даже в этой монолитной модели вы наверняка используете асинхронную коммуникацию с шинами сервисов/событий и прочие приёмы для передачи команд и запросов в другие модули. И именно здесь я нахожу иронию – как это не оказывается более логичным и естественным в ландшафте FaaS?
Модульный монолит – это лишь одна развёртываемая единица, но с хорошим отчётливым разделением кода. Конкретно в нём нет ничего плохого, но теперь мы устремляемся к смешиванию инфраструктурной части с фактическим кодом приложения – что уже нехорошо!
Высокоуровневое представление относительного перехода от плохого к хорошему монолиту, а затем к фактическим микросервисам
Перевод:
1) Связывание конкретной реализации с абстрактным «контекстом». Невозможно отделить «контекст» от развёртываемой единицы.
2) Частичное разделение деталей конкретной реализации друг от друга. «Контекст» и развёртываемая единица по-прежнему находятся 1:1.
3)Полное разделение (кода) по деталям реализации. Теперь «контекст» полностью абстрагирован и гибок.
Позвольте мне быть честным и указать на кое-что немного болезненное: как уже упоминалось выше, те же люди, которые терпят неудачи с микросервисами, зачастую также терпят их и при использовании своей «современной» архитектуры, своей системы коммуникации, при разделении обязанностей… Ведь что такое микросервисы, как не просто инфраструктурное представление этих же, пусть и более абстрактных, концепций? Отчего вдруг с модульным монолитом, да и любым другим, будет легче работать или понимать его, чем нечто, что ясно определено, независимо и семантически дифференцировано?
Микросервисы, в сочетании с обычной логической декомпозицией и проблемно-ориентированным проектированием, могут сделать ваше решение намного более экспрессивным без огромного объёма лишних издержек. Это не так уж сложно.
Иными словами, мне интересно:
Как может одна огромная неопределённая хреновина представлять более удачную архитектуру в сравнении с небольшой грамотно определённой хреновиной?
Мне реально интересно.
Намного более сдержанным подходом здесь, естественно, будет напомнить самим себе о 8 заблуждениях распределённых вычислений и всех способах, которыми сетевые коммуникации могут дать сбой. Добавляя дополнительную зависимость в сеть, мы делаем её в целом более медленной и хрупкой. Это верно отчасти, но каждая архитектура тоже представляет «наименее худший» вариант, поэтому даже человек крайних взглядов должен иметь возможность выбирать, что будет более (или менее) важным – наличие разделения обязанностей, независимой инфраструктуры и возможности развёртывания или же их отсутствие.
▍ Высокая сложность = медленная смерть
По молодости меня ввели в заблуждение, что основной сложностью ПО является математика или нечто похожее и пугающее, что я ненавидел. Намного позже я понял, что это не так – основная сложность по своей природе лингвистическая и процессуальная. Учитывая, что большинство ПО является корпоративным или создаётся для бизнеса, то значительным аспектом является точный и качественный перенос процессов в код.
Поэтому если кто-то также ошибочно считает, что «сложный код» обуславливается «алгоритмами» и «загадочными чёрными ящиками», то я с радостью это заблуждение развею. Хороший код должен, по меньшей мере быть понятным в синтаксисе и структуре (дизайне системы и архитектуре приложения), а также включать достаточный объём грамотной документации, объясняющей и визуализирующей процессы, которые в самом коде неочевидны.
Хороший код примитивен, скучен и предсказуем.
Без лишнего погружения в разбор «плохого и хорошего» кода отмечу лишь, что есть множество средств, которые окажутся полезными для понимания сложности ПО – такой как цикломатическая сложность и зацепление. Могу с уверенностью сказать, что за всю свою карьеру я гораздо чаще использовал степень бакалавра по английскому языку (и полученные гуманитарные знания), чем любой из освоенных мной технических навыков, поскольку этот опыт значительно упрощает решение семантических и организационных проблем.
Сгенерировано с помощью DALL·E. Запрос: an oil painting in the style of the old masters with the devil sitting with a hooded cloak, wrapped and surrounded by snakes made of spaghetti engraved with programming code (картина маслом в стиле старых мастеров – дьявол сидит в плаще, окружённый змеями из спагетти, на которых выгравирован код).
Спагетти-код – это промысел дьявола, и он говорит не только о плохом программировании, но также о пренебрежении и непонимании того, что фактически с его помощью моделировалось. Уверен, что есть должности, на которых трудятся одарённые математики-алгоритмисты и учёные по данным, которые используют «программирование» в широком смысле слова, но не в ориентированном на процессы или социо-техническом контексте. Для остальных же из нас, кто создаёт подобные системы, спагетти-код представляет самое страшное, чего стоит бояться.
Слова обозначают определённые вещи, и если вы этого не понимаете, то должны пересмотреть свою профессию. И мне больно осознавать, что автору классической книги «Clean code» пришлось сильно углубляться в эту тему, чтобы всё прояснить.
Причём наиболее важными словами являются требования или некий аналогичный принцип, используемый вами.
Современные организации вполне могут попросить сотрудников создать что-то не до конца понятное, а инженеры ПО легко могут сказать, что они не могут что-либо протестировать, потому что не знают, как это должно работать (даже если они сами это создали). И это не сложность – это глупость. Иначе такое не назовёшь.
Вследствие недостаточного понимания этой фактически наблюдаемой сложности/глупости, отчасти возникшей в результате отсутствия полноценных или логичных требований, многие организации считают, что разработчики смогут решить (бизнес) сложность на основе любой информации, хорошей или плохой. Увы, это не так.
Типичным заблуждением является предположение, что авторы непонятного кода каким-то образом смогут ясно выразить свои мысли в комментариях.
Корпоративное ПО никогда не может превзойти моделируемый предмет и уровень, на котором он представляется. Индивидуальная способность к осмысливанию, компетентность, внимание и прочие факторы снижают изначальную ценность этого предмета, как только процесс реализации и поставленные требования сталкиваются с реальностью. Так что лучше быть к этому готовым.
Недавно я наблюдал подобное поведение, называемое «логическим долгом», которое прекрасно отражает то, о чём я говорю.
В теории мы вроде как легко можем говорить об имманентной сложности – природе самой проблемы – но в реальности она таким образом не раскрывается. Вместо этого в качестве вторичного эффекта возникает усложнение или, возможно, даже значительная побочная сложность, привносимая со стремлением всё исправить. В результате создаётся ещё больше проблем. Поэтому вместо того, чтобы сохранять чистоту и нацеливаться на корень проблемы (так как мы не можем её полноценно определить), мы уступаем перед искусственной срочностью и прочими вещами, создавая тем самым логический и технический долг.
Возможно, вас заинтересует моя статья по теме технического долга:
Так что реально важный вопрос звучит так: «Неужели мы тоже излишне всё усложняем?» Усложнение, в противоположность сложности, представляет класс проблем, имеющих известные, предсказуемые решения. Не являются ли микросервисы более усложнёнными? В некоторых аспектах да. Хотя не обязательно, если вы используете FaaS или аналогичные подходы. Но при этом вы, естественно, получаете и преимущества.
Пожалуй, самым значимым плюсом микросервисов является то, что они помогают хорошо понять закон Галла:
Сложная работоспособная система всегда развивается из простой системы, которая работала. Сложная система, спроектированная с нуля, никогда не работает и патчами не исправляется. В итоге вам необходимо начинать заново с простой рабочей системы.
Небольшие, «примитивные», вещи работают, естественно, когда у них есть чётко определённые ответственности. Я, как вы уже поняли, утверждаю, что эффективнее использовать для разработки и развёртывания более явный и семантический, лишённый двусмысленности, подход. Как раз микросервисы и позволяют вам его реализовать.
Из-за грубых характерных для монолитной базы кода ограничений такие решения оказываются логически более уязвимы к внесению побочной сложности. Давайте также посмотрим в глаза реальности и поймём, что сложность – это не просто «небольшое трение», она может стать концом вашей работы, карьеры и даже жизней других людей. Число проектов, которые терпят неудачу из-за сложности (включая побочную сложность в результате неудачного планирования, коммуникации и так далее), настолько велико, что сложно даже выбрать примеры. Но ради интереса предлагаю обратить внимание на следующие:
- Windows Vista;
- крушение Boeing 737 Max;
- функциональность автономных автомобилей Tesla;
- система здравоохранения Великобритании;
- катастрофа космического шаттла NASA Challenger;
- «глюк» в Knight Capital Group, стоивший $400M+;
- шведская образовательная платформа «Открытая школа»;
- любые реализации SAP (если верить моим источникам).
Судя по числу анекдотов и различных историй из интернета, в действительности неудачу терпит большинство проектов ПО, что для меня выглядит достаточно правдоподобным.
Дополнительно по теме сложности рекомендую почитать классическую работу Фреда Брукса «No Silver Bullet: Essence and Accident in Software Engineering» (1986) и ознакомиться с концепцией Cynefin.
Сложность не является абстрактной, она осязаема. Спросите любого, кто пишет код.
Насколько мне известно, инженерное искусство стремится к сокращению числа неизвестных и сложности. Если в итоге этого не происходит, то это уже не инженерия. И сокрытие деталей системы в неопределяемом чёрном ящике лично для меня явно выглядит неудачной идеей.
Таким образом, монолит заключает в себе стремительный регресс. Нацеливаясь на простоту, он по своей сути не может справиться с обработкой нарастающей сложности. Естественно, в монолите вы получаете меньше швов, но они нужны, чтобы разделять, именовать и идентифицировать различные нужды. Именование является одним из двух «трудных аспектов» в компьютерной науке, и при этом всё равно не таким трудным, как проектирование ПО. Здесь вам необходимо именовать, разделять и дифференцировать множество элементов, переходя от чана со спагетти к микросервисам. Да, может быть проще в некотором смысле развернуть монолит, но каждое изменение в нём может влиять на всё остальное. Это плохо.
При этом будет недальновидным использовать такие сравнения, как «Ну мы же не Netflix» или «У нас не комплексная система». Дело в том, что практически всё в сфере вычислений является распределённым – то есть у вас уже есть распределённая система.
Монолиты обладают техническими свойствами, отличными от микросервисов, но болевые места последних особо досаждают некоторым специалистам из-за неразрешённой сложности и нечётких ментальных моделей. По Фрейду нападки на микросервисы можно также воспринимать как замашки агрессоров, объясняющие, чего им самим не хватает.
Люди и их коллективы (то есть команды) являются центральным аспектом модели DevOps. Чисто логически ничто не указывает на то, что всеми микросервисами не может обладать и управлять одна команда. Разногласие возникает, когда речь заходит о распределении всего. И я задаюсь вопросом: «Почему это должно быть проблемой – создавать системы с границами и просить людей отвечать за разные части?»
То же касается тех, кто жалуется, что микросервисы плохие или трудные, так как могут потребовать (?) совместного развёртывания изменений – вы полностью упустили важнейшую работу по изолированию вашего сервиса. Это не проблема микросервисов, это ваша проблема.
Так что, может, пора менять своё мнение? Жёсткий факт: если ваша организация неспособна адаптироваться к конкретным, в основном непересекающимся продуктам/возможностям/принципам, тогда да, с микросервисами будет нелегко. Но они всё равно могут оказаться более удачным решением (в качестве переходного этапа), чем грязевой ком монолита, так как вы получите описанные выше преимущества, в которых я не сомневаюсь. Это вполне может того стоить.
▍ Утрата языка и последствия
Мы слишком много думаем о ПО и слишком мало о всём, что его окружает.
Код предназначен для решения проблем. Если мы не сможем изложить задачу и желаемое состояние, то не должны (даже не можем) предложить и создать для неё решение.
Я бы сказал, что ошибки в управлении и проблемы с процессами возникают в результате использования решения без полного понимания задачи и учитывания того, что всё со временем меняется.
Если, не дай Бог, код реально станет проблемой, то мы окажемся в глубокой ж*пе, окружённые вдвое бо́льшим числом проблем. И это произойдёт по логике вещей, поскольку код делает «что-то», но это «что-то» ещё нужно определить (примечание: не в положительном «гибком» смысле).
И «бизнес» никогда не будет жаловаться на первую «неизвестную/непостижимую» проблему (которая осязаема), только на новую, которую вы только что создали, стараясь быть «хорошим мальчиком» и качественно делать свою работу.
Это вы в образе хорошего мальчика. Печально, но хороший мальчик, тем не менее, делает лишь то, что ему велят. А вот книжка, которую можете почитать своей собаке.
Рассмотрим более широкую картину.
Я считаю, что отчасти такое положение дел вызвано недостатком обучения людей в нашем обществе критическому и рациональному мышлению. Наша система образования также не обеспечивает качественную подготовку бизнес-аналитиков, инженеров и прочих IT-специалистов. Отлично по этому поводу написал Джим Ахо в своей статье.
Меня сильно пугает то, куда катиться наша система образования. Утрата критического мышления, соответствующих контексту действий и инициативы, утрата языка (плохая грамматика = плохой код, и это вполне реальная проблема) никак не повышают статистическую вероятность создания эффективных организаций, «вещей» и решений для жизненных проблем.
И сфера Big Tech согласна, что эти навыки важны, о чём писала Ирина Станеску на LinkedIn:
За свою 14-летнюю карьеру на должностях в крупных технологических компаниях, таких как Google и Uber, из всех навыков я чаще всего использовала письмо. И нет, я не имею ввиду написание кода. Я говорю об английском письме. Электронные письма, диздоки, презентации, обратная связь, код-ревью и так далее.
Подобно Данте, всё глубже спускающемуся в ад, мы видим всё больше свидетельств этого падения и его влияния на разработку ПО. Основным примером такого положения дел являются давние идеи, которые от замысла переносятся никак не к реализации, а только к пунктам Powerpoint и срочным «целевым группам», которые создаются, а затем просто распускаются. Принятие плохо обученных людей, которые едва справляются со своими управленческими обязанностями, представляет настолько удручающее состояние, что даже его оценки в финансовых убытках будет недостаточно.
Я приведу вам пару личных примеров, пусть даже и не столь экстремальных.
▍ «Простая» мега-задача
Я помню, как много лет назад пытался объяснить Kanban своему коллеге, который работал на стороне проекта/продукта. Немного поразмыслив, он сказал:
«А нельзя это просто объединить в один пункт: выполнить задачу?»
▍ Схема с чёрным ящиком для решения всех задач
Однажды мне пришлось буквально обозвать представленную на рассмотрение «архитектуру» «диаграммой Дональда Дака», так как она должна была отражать ключевую функциональность, но по факту едва дотягивала даже до мультяшной зарисовки. И я не горжусь этим своим заявлением, но где-то нам приходиться проводить линию между искренностью и учтивым киванием, ведущим к провалу. Сроки поджимали, а великие умы придумали вот это?
В стремлении исправить ситуацию мы с тех пор продумали и наладили работу этой ключевой области, а сам тот случай просто стал напоминанием, что плохие вещи случаются, когда к самостоятельной работе допускаются не те люди. Было бы приятно узнать об этой обратной стороне медали из всех этих беззаботных исследований DX (Developer Experience, опыт разработчика).
Примечание: это не оправдывает ARB* или ITIL*, но чёрт побери – некоторым людям реально нужно менять карьеру.
Architecture Review Board – ревизионная комиссия по архитектуре.
Information Technology Infrastructure Library – библиотека инфраструктуры информационных технологий.
Без знания языка и сопровождающих навыков/организации/структуры никак не получится решить эту дилемму со сложностью. Я ещё не встречал профессионала, умеющего выражать области, модели, границы и технические интерфейсы, который после налаживания работы микросервисов захотел бы вернуться к монолитной архитектуре (хорошим контр-примером является случай с Amazon Prime).
К тому же я редко вижу критику, которая адекватно – или в принципе – демонстрирует какие-либо познания профессиональных особенностей, описанных в основной литературе по нашей профессии. Просто невозможно узнать, как люди готовились к использованию микросервисов, но для меня немыслима сама возможность этих их провалов, проделай они всю необходимую подготовку (как я уже неоднократно говорил).
Возможность работать с микросервисами и современными распределёнными архитектурами, как всегда, основывается на вашем применении навыков, которые всегда были частью обязанностей инженера ПО. Этой широты и «грамотности» нам не хватает сейчас, когда в результате 10-15 лет ультра-нишевых должностных обязанностей и 6-недельных программ подготовки к IT-профессии индустрия оказалась в упадке и заполнена людьми с низким уровнем навыков, а также страдающими от всего этого организациями.
Я имею ввиду следующее: вы увидите, что крупные технологические компании много внимания уделяют вашим социальным, а также литературным навыкам, выражающимся в код-ревью, проектировании систем и аргументировании возможных решений. А вы нет? Создание распределённых систем в 2023 году уже не является чем-то «уникальным». Всё это несложно освоить, но бо́льшую часть из этих навыков вы получите не за клавиатурой. Клавиатурный воин-интроверт – это не тот образ, который предполагался для инженера ПО.
Кто-то должен в чём-то проявить инициативу: почему, чёрт возьми, наши организации и кадровики принимают всё это? Утрата грамотности и всех этих важных общечеловеческих качеств в результате тупого набора синтаксиса понижает наши шансы на получение достойной профессии. Роберт К. Мартин даже писал о разработке ПО, как о не заслуживающей называться «профессией» в строгом смысле слова. Ведь, в конце концов, чем конкретно мы овладеваем? Я думаю, этот вопрос уместен, когда мы с трудом справляемся с масштабной «инженерной» частью в плане нашего взаимодействия со стейкхолдерами.
▍ Напоследок: более простое будущее
Сложность и индустрия самосовершенствования в некотором смысле похожи. Иронично, но книги о самосовершенствовании или тонко завуалированные программы (даже что-то безобидное вроде Bullet Journal) будут преподносить некую ключевую ценность или достоинство как желаемое, сообщая что именно это конкретное руководство «раскроет» вам, как можно, следуя программе, получить это желаемое – время, деньги, энергию, сон, стройное тело, что угодно.
Согласно свойственному нам стайному и банальному человеческому поведению, мы будем планировать и структурировать эту необходимую работу, следуя нашей новой философии жизни или смутному сиюминутному порыву. А ведь большинство книг по самосовершенствованию в действительности не работают. Я считаю всё дело в том, что во многих случаях их авторы действительно верят в свою программу – для них она сработала! Возможно, она сработала и для некоторых других. Но суть такова, что психология – это поистине сложная (в реальном своём смысле) штука. То, сработает она для вас или нет, тоже будет в основном определяться удачей, настойчивостью и тем, что лучше подходит именно вашей личности.
Большинство программ заявляются как простые или нечто в таком духе, чтобы это вписывалось в контекст. Тем не менее они лишь нацелены на увеличение, то есть призывают «делать больше того или другого». Я всегда считал себя больше редукционистом, и меня привлекал дзен-буддизм (хотя последователем этого духовного течения я никогда не был).
Но я пытаюсь жить по правилу меньшего: удалять лишние варианты. Носи одну стрижку. Одевайся однообразно. В итоге будешь свободнее.
В качестве награды я получаю высвобожденную энергию, которую могу направить туда, где она реально нужна. Я существенно расширяю возможность тратить время на те занятия, которые мне интересны, что явно не касается большинства людей, мечущихся между работой, детьми, развлечениями и прочими задачами.
Не позволяйте своему увлечению решением сложных задач погрязнуть в пучине усложнения и неопределённости.
Ответом на уменьшение сложности будет стремление к меньшему числу движущихся деталей и к более точным определениям назначения той или иной вещи. Не создавайте то, что уже существует в готовом и доступном виде. Не создавайте то, что не понимаете и не можете нарисовать, обсудить или объяснить. Несмотря на то что в монолите внешне как бы меньше движущихся деталей, это лишь потому, что мы скрываем их в чёрном ящике без пояснений.
Пользуйтесь литературой по проектированию – нам нужно стремиться расширять словарный запас, а также оценивать, к примеру, аффордансы (термин Дональда Нормана) и то, как ограничения в действительности могут улучшить нашу работу. Проясняйте задачу и упрощайте её решения. Технологическая среда излишне стремится к новизне, и это больше вредит нам, нежели помогает. Но микросервисы не являются какой-то очередной «новинкой», это инфраструктурное представление отчётливых ответственностей, которое всегда останется актуальным.
Узнавайте о новых акциях и промокодах первыми из нашего Telegram-канала ????
Комментарии (33)
Apoheliy
30.10.2023 13:20+3По мне - ужасная статья и перевод. Даже ниосилил, извините. По переводу: какие-то несогласованные части в предложениях (автоматизированный перевод?), частое использование цитат (выделить очень умные мысли?). По статье всё ещё хуже - её можно представить фабулой: давайте представим, что микросервисы лучше монолитов; теперь давайте из этих предпосылок докажем, что микросервисы лучше монолитов. Очевидно, что взяв за основу спорное утверждение, в результате получим тоже что-то спорное.
-
По теме сравнения микросервисов и монолитов:
Обычно читаю про рассуждения о параллельности разработки, наращивании производительности и куче других (вероятно, полезных) вещей.
Что обычно остаётся за обсуждением: если ваша система работает на внешнем объекте без доступа к интернету, то микросервисы (как бы) применять можно, только работать это будет недолго. И все микросервисы "превращаются в тыкву". И такие "затыки" могут быть не только с интернетом. Вместо этого у человечка:
Лично для меня абсолютно логично утверждение, что многие организации и люди, решительно отвергающие микросервисы, никогда не оказывались в успешных условиях
Хотя, наверное, доля правды есть: если работать в условном Гугле, то ты будешь работать с микросервисами и, возможно, ты окажешься в успешных условиях (что бы это ни было). Это такой сарказм.
igor_sheludko
30.10.2023 13:20Пожалуйста, поясните, как отсутствие интернета мешает работать микросервисам?
Apoheliy
30.10.2023 13:20+1Всё же уточнюсь по ограничениям:
на внешнем объекте без доступа к интернету
-
Вся та информация, которую собрал по процессу поддержки микросервисов сводилась к тому, что мы много чего логируем, много чего мониторим. И всё это делаем в (почти) реальном времени. И если есть какие-то проблемы: требуется что-то перезапустить!!!, где-то подправить код - то включается "счётчик" и в течение минут/часов это всё исправляется, перезапускается, или на крайний случай откатывается к предыдущему варианту.
И теперь представьте: у вас стоит система на внешнем объекте. На объекте есть инженеры, и они могут тупо-глупо что-то перезапустить (после общения по телефону), логи выслать на почту или сфоткать скрин. И это всё.
Как результат: логов нет (инженеры на объекте сами читать логи не будут :), передавать их вам через почту: при явных проблемах - да, постоянно - нет), мониторинг инженеры могут смотреть, но очень высокоуровнево. Заменить ПО (т.е. вы отсылаете дистрибутивы или пакеты инженерам через почту/внешние хранилище) через инженеров объекта вы не захотите (ну, если вы не камикадзе, так как все шишки полетят в вас). Откатиться - ну технически это можно, но тоже "жим-жим". Из нормальных решений это перезапуск и замена оборудования из ЗИП (это если ЗИП настроится сам или по простой инструкции).
С моей точки зрения, микросервисная архитектура при этом
работать это будет недолго
В общем, до первого "глючка"/сбоя.
Прим.: физически до объекта ехать/лететь - это дни/недели.
-
Может, Вы расскажете Свой взгляд на работу микросервисов на внешнем объекте без доступа к интернету? Здравые предложения приветствуются.
igor_sheludko
30.10.2023 13:20+1В описанной вами ситуации я не вижу разницы с монолитом - там будут примерно те же трудности.
За исключением того, что в случае микросервисов, если сбоит не сильно критичный сервис, то можно его отключить и иметь больше времени на фикс, тест фикса и запуск обновления.
Кроме того, перед запуском релиза обычно все таки делается достаточно масштабное тестирование, да и резервная система с предыдущим стабильным релизом тоже не помешает.Также я сомневаюсь в реальности серьезных трудностей от сценария, который вы описали - при любой реализации системы.
interprise
30.10.2023 13:20+4Я чисто физически не понимаю, как вместо вызова метода, сериализация - передача по сети - десериализация, может быть эффективна. Так еще если возникнут проблему, нужно либо обращаться к другой команде либо смотреть не типичный для тебя код. Плюс, допустим у вас есть состояние в приложении, нужно как-то синхронизировать это состояние между несколькими микросервисами (или делать запрос каждый раз для получения этого состояния). Я вижу просто работу ради работы. Да можно писать на разных языках в одном проекте, но серьезно, оно вам надо? Больше всего раздражает, что теперь на любом собеседовании тебя спросят про микросервисы и ты с умным лицом должен рассказать об их плюсах.
hardtop
30.10.2023 13:20Конечно одни плюсы: Серверов потребуется больше (снабженцы смогут откатить себе), команды придётся увеличивать (HR будут почти принцами), программерам купят новые компы, чтобы по докерам распихать всё великолепие… И асинхронности, больше асинхронности!
alexdora
30.10.2023 13:20+2А потом когда все это купили и весь народ нанят, надо еще сверху купить 20% и потратить еще 50% человекоресурсов чтобы подключить/настроить/создать систему мониторинга. А то как же руководству потом показывать красивые графики?
hardtop
30.10.2023 13:20+1Сдаётся мне, что автор троллит и изначально повышает концентрацию го*на и вентиляторов
alexdora
30.10.2023 13:20+12Расскажу свою историю
Был проект который с самого начала писался мной, состоял он из *ярда микросервисов. Притом были микросервисы которые писал я, были те которые взяты с других проектов или сделаны другими людьми. Естественно, проект не обошло все то что любят сисадмины: много всяких разных виртуалок, кучу систем мониторинга каждого пука. Все выглядело как рождественская елка которую наряжали годами, там у тебя API с WS, там ZeroMQ...там еще что-то. И скажу честно, на тот момент я верил что система идеальна.
Но идеального нет и мир был прекрасен до того момента пока не появилась задача ускорить работу. И тут стоит отметить что сама задача имела четкое финансовое обоснование – быстрее, значит больше денег приносит.
Я начал поиски как же ускорить и то что лежало на поверхности – различные протоколы взаимодействия микросервисов. Во время теста зоопарка протоколов включая IPC и UDP даже дошел до варианта убить де/сериализацию с помощью байтового представления. Т.е пакет кидал прям в байтах чтобы избежать трату времени на разбор. Но результаты оказались скромные, если мне не изменяет память была 1мс, стало 0.4мс. Конечно, кому-то покажется что это результат-результат, но на самом деле это как раз ускорение на базе UDP протокола где использовался бинар и требовалось очень много переписывать. Т.е 0.6мс не стоят этого.
В итоге пришло все к думам на тему монолита. Мозг не хотел принимать эту схему, самые частые мысли – а если ошибка в коде, там же все рухнет. И привычка дело такое, что на первой стадии разработки мысли эти не покидали. Тогда мозг не хотел понимать, что если в одном из микросервисов ошибка – все и так не будет корректно работать
Год я переписывал это чудо. Помню что лишь через 2-3 месяца от начала разработки до меня стало доезжать насколько микросервисы – пережиток прошлого и некий рекламный булшит. Отчетливо помню, как при разработке отыгрывали старые привычки: "о тут надо же сделать мониторинг...а потом такой – а зачем тут мониторинг, оно и так имеет только два статуса: либо работает, либо все рухнуло сразу вместе с приложением"
И когда все было закончено и запущено в прод тогда-то и наступило осознание, что надо было делать это раньше. Не говорю о скорости взаимодействия, которое теперь измеряется в тысячах наносекунд, – все таки это специфическая задача конкретного проекта. Говорю о том что подход к коду стал "ответственнее", ушло кучу мусора в том числе различных мониторингов, виртуалок и тд...освободились ресурсы. Вот к примеру про ресурсы, с 8 серверов которые были загружены под 70% теперь все живет на одном. А эти 7 перепрофилировали на резерв и различные другие функции. Что освободится такое количество ресурсов даже в сказке представить никто не мог.
В заключение хочу сказать вот что. Безусловно, микросервисная архитектура имеет право на жизнь, где-то она действительно необходима (хотя после моего опыта придумать у меня не получается). Но если перевести в понятную математику, то получится что запустить условно приложение на микросервисах понадобится наверное на 20% времени меньше и это плюс...более быстрый запуск так сказать, но обслуживание потом будет тратить это время в геометрической прогрессии с увеличением самого проекта. И хорошо если это время чье-то чужое или оплачиваемое, а не ваше личное.Apoheliy
30.10.2023 13:20В своё время примеривался к идее микросервисов, обсматривал как в соседних компаниях сделано, считал оверхед. Получил примерный общий вывод:
Потребляемые мощности микросервисной архитектуры и монолитной относятся примерно как 10:1 - 20:1 (в зависимости от логирования, мониторинга и др.).
Как результат, микросервисы имеют смысл (в разрезе вычислительной мощности) если всё это будет нагружать 20+ серверов. Возможно это временная ситуация (на пиковых нагрузках), или с заделом на будущее. Понятно, что "сервер" - это расплывчатое понятие (у кого-то они слабее, у кого-то мощнее), но для оценки это подходит: граница в 20 шт. - она примерно там и остаётся.
Если же микросервисы стабильно потребляют мощности меньше 20 серверов, то лучше делать не-микросервисы. Прим.: не очень люблю слово "монолит", т.к. вариантов реализации там много и не всё совсем уж монолитное.
И в обратную сторону: если сильно не хватает мощности одного сервера, то пишем (переписываем под ...) микросервисы и сразу обкладываемся вычислительными мощностями на оверхед.
alexdora
30.10.2023 13:20Тут я хотел бы отметить, и думаю вы тоже это понимаете если есть условный монолит который утилизирует вычислительную мощность 1 условного сервера, то при появлении запроса на расширение этой мощности – доработать монолит для "клонирования" не является сверхзадачей. Это субъективно мое мнение.
Вы довольно четко попали в мою математику по соотношению 1:10 (у меня 1:8 получилось). Если представить гипотетическую ситуацию что некий проект начат с микросервисов и растет как на грибах...допустим, он вырос до 100 серверов. Рано или поздно кто-то появится и займется оптимизацией. Оптимизировать такое – дорого (я даже не говорю о том чтобы переписать все на монолит, а просто уменьшить количество микросервисов для увеличения утилизации ресурсов) и при всем при этом это надо все поддерживать чтобы работало. Ну и конечно не забываем о самом оборудовании, чем больше количество – тем больше отказов
А если мы возьмем обратную ситуацию, написан изначально монолит и хочется зачем-то перевести его на микросервис – это довольно просто будет, считай дробишь одно на какие-то части и налаживаешь связку. Хотя я не особо представляю такой кейс.
Пока честно, я пытаюсь представить различные кейсы в голове при каких условиях надо начинать проект с микросервисов и не могу их придумать. Может кто-то придет и расскажет свое видение, с удовольствием почитаюigor_sheludko
30.10.2023 13:20Интересно было бы увидеть расчеты. С учетом того, что сервисы запускаются в контейнерах и малонагруженные сервисы могут жить на одном сервере в большом количестве, вплоть до десятков штук, пропорция 1:8 вызывает сомнения.
Если монолит изначально был спроектирован плохо - без четкого разделения на модули, то дробить его на части - это серьезная работа, может быть даже настолько серьезная, что проще рядом новую систему разработать.
Начинают проект с микросервисов обычно тогда, когда система разрабатывается для продажи (это продукт), а не под единственного заказчика. А также когда четко видна модульность и понятно, что разным покупателям будут поставляться разные конфигурации модулей.
Также добавлю, что современные фреймворки помогают разрабатывать микросервисные решения с возможностью развертывания сервисов как в отдельных процессах, так и группировать несколько плотно взаимодействующих сервисов в одном процессе (тогда упрощается коммуникация - происходит просто вызов функции в одном адресном пространстве и сериализация/десериализация не выполняются).
В случае интерпретируемых ЯП, например, JS/TS для изменения конфигурации запуска можно даже не пересобирать приложения и контейнеры. Файлы конфигурации запуска сервисов могут использовать переменные среды и в итоге это все может конфигурироваться на уровне параметров запуска контейнеров.
То есть систему, спроектированную в микросервисной архитектуре можно запускать как монолитом - одним процессом, так и кластерами сервисов, вплоть до кластеров, состоящих из одного сервиса. И все это без изменения бизнес-логики. Просто исходя из необходимости - нагрузок, доступной инфраструктуры.
igor_sheludko
30.10.2023 13:20Это довольно типичная ошибка - излишне подробное дробление задачи на сервисы. Апогеем этого безумия является упомянутое в статье - Function as a Service, этот подход продвигают компании, которые продают условный "хостинг" - чем больше народ на это подсядет, тем больше они заработают.
JordanCpp
30.10.2023 13:20+2Думаю, что всё намного проще. Если вы не авито, гугл, яндекс. То вам не нужны микросервисы. Если вы пиццерия, или леруа мерлен, они вам зачем?
Сейчас любой средний сервер, потянет все ваши данные. Если вдруг упретесь всегда есть шардинг. Пока разрабатывают микросервис, занимаются тестированием, согласованием API,. Вы просто ставите ещё один сервак на чтение и нагрузка на железо падает на 50%.
igor_sheludko
30.10.2023 13:20Нормальное решение, если у вас в системе преобладает чтение данных, а если 50 на 50 с записью, или запись преобладает, то выгода будет поменьше?
JordanCpp
30.10.2023 13:20По крайней мере снизится нагрузка на чтение. И освободятся доп ресурсы. Ну и запись независима от чтения. Ускорение будет, но сказать насколько не берусь.
Я больше исхожу из практичности и просто ты. Если пиццерия как некая константа функционала требует 100 микросервисов, для работы. Явно, что то пошло не так.
igor_sheludko
30.10.2023 13:20Если в одной системе сервисов около 100, то явно нужно разбираться, что же пошло не так
finddelst
30.10.2023 13:20Перевод тяжело читается. Но в целом он близок к тому, что хотел сказать автор. Я поддержу автора, очень многие концепции идут в пересечении с организацией людей и хорошего проектирования.
Закон Конвея. Для команды важна изолированность ее решений, чтоб снизить влияние других команд на ее код. Микросервисы и отдельный репозиторий помогает в этом. В любом монолите будет общий код и его изменение затрагивает все команды и придется много потратить времени на глобальный регресс.
-
Возрастающие сложности:
Проблемы при разработке. Я видел проекты, где монолит нельзя было поднять локально у разработчика, для каждого пришлось выделять отдельную виртуалку, с микросервисами и например микрофронтендами в такое очень сложно упереться.
БД в Монолите единая, в отличии от микросервисов, что создает проблемы например для zero-downtime изменений (пример нужно изменить формат поля). С легковесными микросервисами и отдельным схемами/базы данными это проще
Монолит обычно не может быстро деплоиться , обычно собирают кучу МР и выкатывают например раз в 30 минут. Каждый МР успешно прошел, но когда они сливаются вместе, вы получаете ошибку. И дальше начинаются проблемы, например найти нужный МР, который привел к ошибке.
Обновление внешних библиотек, отдельная боль. Никто не обещает обратной совместимости, вам придется потратить кучу сил на синхронизацию команд, такое обновление должно быть единомоментным. В отличии от микросервисов, где каждая команда в своем ритме может это сделать.
Производительность, это отдельная тема, чисто на бумаге да, микросервисы тратят дополнительное время. Но зачастую вся проблема не в общении между микросервисами, а где то еще. Если у вам много общения между микросервисами, то возможно вы плохо спроектировали их. Но тут да, еще раз повторюсь на бумаге, производительность ниже.
Как итог, я полностью поддерживаю автора в том ключе, что возрастающая сложность - это самая большая проблема. Как в примере с чистой архитектурой, приходится платить много рутинным и банальным кодом, чтоб изолировать доменную область, чтобы снизить эту сложность. Так и в микросервисах, приходится обвязывать многими банальным,а иногда нет, инфраструктурными вещами ,которые кстати ложатся не на плечи разработчиков, чтоб бы снизить эту сложность для разработки.
JordanCpp
30.10.2023 13:20+3Разграничение интерфейсами и функциональными доменами.
1 Я видел проекты где разработчики пытались поднимать 100500 микросервисов, но ПК не тянул. Невозможно локально поднять все и сервисы. С монолитом проще.
2 Всё покрыто интерфейсами и обращение за данными через них. Если по коду разбросано select поле1, а нужно поле_2 это проблема не из за монолита.
Можно разворачивать несколько монолитов для теста. Одни пилят одну фичу тестируют на одном контуре, другие на другом. Потом уже есть финальная сборка.
Ага. У всех разные библиотеки. Допустим прилетает библиотека с исправлением, у одной команды всё ок. Несколько микросервисов при работе сломались. Идёт разбирательства кто виноват. Оказывается остальные которые не обновили библиотеку в своём микросервисе. Работает же.
Разделили на микросервисы. Архитектор доволен. Всё чувствуют себя Мега программистами. А потом микросервис доставок полез в микросервис юзеров, юзеры полезли в историю покупок. Заказы идут опять в юзеров и в итоге с опозданием когда отработал код распределённых транзакций мы получили две требуемы строчки пробившись через сеть. А что делает монолит, одним запросом забирает данные. Всё происходит быстро так как находится в едином адресном пространстве. А ещё по дороге что то посчитал, так как это быстрее чем считать на клиенте.
В итоге не всё так просто и в лоб не сравнить.
finddelst
30.10.2023 13:20И как ты этим единый репозиторий кода разделишь?
Зачем мне разворачивать все микросервисы? я вряд ли буду вносить во все изменения. Мне нужен минимум чтоб сделать свою задачу.
Надеюсь ты знаешь как решается задача zero-downtime для изменения БД например типа одной колонки и в чем сложность
Я описал проблему именно когда сливают несколько фич в финальную сборку, они же могут влиять друг на друга? Может же ломаться?
Раздолбайство не лечится архитектурой.
Если ты почитаешь статью, то автор говорит о том что разработка должна быть без сложностей и "мегапрограммисты" обычно создают проблемы. И твой пример при распределенных транзакциях - это не к микросервисам, это уже ближе SOA, где распределнную транзакцию можно в оркестраторе бизнес процессов реализовать.
PuerteMuerte
30.10.2023 13:20+1И как ты этим единый репозиторий кода разделишь?
Такая потребность, это очень-очень частный случай. Обычно вполне достаточно, если другая команда просто работает с отдельными модулями в рамках общей репы
Зачем мне разворачивать все микросервисы? я вряд ли буду вносить во все изменения. Мне нужен минимум чтоб сделать свою задачу.
А как ты узнаешь, затронули ли твои изменения работу других сервисов? Деплоем в тестовую среду и ожиданием, пока там интеграционные тесты отработают, и если что-то пошло не так, то повторением цикла изменений/тестов? Это долго и непродуктивно.
Надеюсь ты знаешь как решается задача zero-downtime для изменения
Deployment slots
Я описал проблему именно когда сливают несколько фич в финальную сборку, они же могут влиять друг на друга? Может же ломаться?
Могут, но в монолите-то они никак не окажутся внезапно вместе в финальной сборке. До этого они побудут все вместе в тестовой сборке, где возможные конфликты и должны выявляться.
Раздолбайство не лечится архитектурой.
Это факт :)
finddelst
30.10.2023 13:20Такая потребность, это очень-очень частный случай. Обычно вполне достаточно, если другая команда просто работает с отдельными модулями в рамках общей репы
речь шла о кейсе, когда есть общий код для всех. Если он меняется, например тип какого то поля, удобно же что IDE тебе подсветит все места где надо изменить. Но данное поле еще сохраняется где то в БД, надо будет еще единую миграцию сделать по всем таким случаем. И если мы возьмем большую компанию 100+ разработчиков, я думаю это будет неприятным организационным моментом.
А как ты узнаешь, затронули ли твои изменения работу других сервисов? Деплоем в тестовую среду и ожиданием, пока там интеграционные тесты отработают, и если что-то пошло не так, то повторением цикла изменений/тестов? Это долго и непродуктивно.
Опять же речь шла о локальной разработке. Мне для решения хочется поднять локально код и проверить что он работает. Мне не нужно поднимать 100500 сервисов. Чтоб узнать о том что затронули или нет, всегда есть контрактные тесты. Понятно что в монолите можно написать больше дешевых тестов для отладки взаимодействия между командами. Но это уже другой вопрос. Тут конечно сложнее микросервисам, поэтому придумали контрактные тесты. Такой кейс кстати есть и в монолите - между фронтом и бэком.
Могут, но в монолите-то они никак не окажутся внезапно вместе в финальной сборке. До этого они побудут все вместе в тестовой сборке, где возможные конфликты и должны выявляться.
выше писали что в финальной сборке все окажуться вместе. я конечно за то чтоб как можно раньше выявить проблему. Вот у тебя 30 мров в тестовой сборке и она падает. И начинаются танцы поиска проблемы, особенно если тот кто закоммитил и ушел пить кофе по-ирландски. Понятно, что все решается, но просто из-за упавшей сборке, все должны отвлечься и посмотреть кто накосячил.
Мой довод в том что микросервисы лучше разграничивают зону ответственности команд, но конечно это небесплатно. И архитектура должна помогать не делать глупости. Как бы ты не хотел в микросервисах ты не сможешь вызывать методы другой команды мимо API или залезть в БД, в отличии монолита. Умники всегда найдутся "потому что сроки горят".
PuerteMuerte
30.10.2023 13:20+1Но данное поле еще сохраняется где то в БД, надо будет еще единую миграцию сделать по всем таким случаем. И если мы возьмем большую компанию 100+ разработчиков, я думаю это будет неприятным организационным моментом.
Да, но это абсолютно то же самое, что поменять тип поля в микросервисе. В монолитах (дисклеймер: я не имею в виду откровенно жопную архитектуру, при желании испортить можно всё) тоже не бывает такого, что одно поле влияет на всё везде. За каждую сущность отвечает какой-то конкретный сервис, к которому обращаются другие сервисы. Если вы конкретно работаете с данным сервисом, вы и затронете только его же данные. Конечно, я имею в виду современный монолит. Если взять какое-нибудь легаси, где бизнес-логика вообще всунута в хранимые процедуры, как это было модно в 90-е, там точно будут нюансы :)
Опять же речь шла о локальной разработке. Мне для решения хочется поднять локально код и проверить что он работает
Ну я как бы и локально хочу сразу знать не просто, что код проходит юнит-тесты, а то, что он не ломает ничего вокруг. Не знаю, как у вас, а у меня во всех проектах ничего существенного юнит-тесты не находят, самые серьёзные ошибки всегда на интеграционных выскакивают.
Вот у тебя 30 мров в тестовой сборке и она падает. И начинаются танцы поиска проблемы, особенно если тот кто закоммитил и ушел пить кофе по-ирландски
Так с микросервисами будет всё то же самое, но вы об этом узнаете не локально, а уже после публикации :)
И архитектура должна помогать не делать глупости.
Да, такой момент есть: в монолите куда больше свободы выбора сделать кривую архитектуру
finddelst
30.10.2023 13:20Да, но это абсолютно то же самое, что поменять тип поля в микросервисе.
Про поле не понял) всегда есть версионность api, есть конечно минусы, версий не напасешься на все случаи. второй момент, если из одного простого типа в другой тип, то куча возможностей при сериализации можно использовать. поэтому не соглашусь что таже проблема)
Ну я как бы и локально хочу сразу знать не просто, что код проходит юнит-тесты, а то, что он не ломает ничего вокруг. Не знаю, как у вас, а у меня во всех проектах ничего существенного юнит-тесты не находят, самые серьёзные ошибки всегда на интеграционных выскакивают.
ну вот у меня сейчас проект, монолит отдельно стоит на виртуалке, с отдельной БД. потому что локально это не поднять. с микросервисом иначе. да, можете поднять все необходимые микросервисы, и интеграционные прогнать на нужных вам отдельных модулях. вряд ли вам нужны прям все микросервисы
Так с микросервисами будет всё то же самое, но вы об этом узнаете не локально, а уже после публикации :)
не будет, у тебя отдельный микросервис у команды, она его деплоит когда хочет и никого не ждет. понятно что надо соблюсти все понятия обратносовместимости и версионнирования. но это полностью отвязывает от ожидания других команд.
JordanCpp
30.10.2023 13:20Я выше писал. Что не имеет смысла баловаться с микросервисами получая лишнюю сложность, так как при малом количестве данных, пользователей, вы не получите отдачу пропорционально технологии. Получите только сложность разработки, поддержки, выкатывания и тестирования. И зачем тогда всё это нужно. Технология ради технологии?
JordanCpp
30.10.2023 13:20+1И добавлю. Микросервисы тормозят, так накладывают оверхед, на сеть, на распределённую транзакцию, на синхронизацию. В монолите на себя это всё берёт БД из коробки.
Практика критерий истины. Просто практика зависит от данных.
PuerteMuerte
Как по мне, автор не объективен, а просто топит за схему, которая лично ему больше нравится. В реальности микросервисы не есть шаг вперёд по сравнению с модульным монолитом. Да, эволюционно они появились позже монолитов, но тем не менее, эта архитектура имеет рамки применения, где у неё есть преимущества:
Части вашего приложения разрабатываются независимыми командами
Нагрузка на разные компоненты вашего приложения имеет такой характер, что вы при его масштабировании получаете бОльшую выгоду от разнесения компонент на разные хосты, чем просто от увеличения количества экземпляров.
Пожалуй, это всё. В остальном модульный монолит либо имеет паритет с микросервисами
Возможность независимо разрабатывать компоненты приложения есть и там, и там
Грамотное проектирование модульного монолита по сложности примерно такое же, как и грамотное проектирование микросервисов
Возможность деплоить только изменённые компоненты у микросервисов нивелируется возможностью использовать слоты деплоя у монолита
...либо имеет преимущества, например
Существенно более высокую производительность приложения, т.к. вместо общения через хттп юзаются обычные внутренние вызовы
Упрощаются и ускоряются интеграционные тесты
В общем, как мне кажется, в большинстве случаев практичнее иметь модульный монолит, нежели набор микросервисов.
Ares_ekb
Для меня это спорный вопрос. Сами термины вполне возможно что появились одновременно, когда люди начали противопоставлять монолиты и микросервисы. Но какой из подходов более новый и прогрессивный... Прообразы микросервисной архитектуры на мой взгляд были и раньше.
Когда-то давно я работал в медицинском центре. Там для каждого подразделения, под каждую задачу была своя небольшая информационная система. Делались они на чём угодно - FoxPro, Delphi + Firebird, Access, C# + MS SQL, Java. Сами по себе эти системы были вполне норм, писались умными людьми и решали свою задачу. Но когда их количество достигло критической массы, то стали возникать вопросы: 1) а почему отчеты, построенные в разных системах не бьются между собой? 2) как вообще собрать эти отчеты без ручной работы? 3) можно ли как-то уменьшить дублирование работы операторов, потому что часто они вносят в разные системы пересекающиеся данные? 4) можно ли как-то в одной системе посмотреть данные из другой системы, чтобы не устанавливать себе десятки приложений?
Нужно было всё это как-то интегрировать. И было два пути:
1) Довести всё это до труЪ микросервисной архитектуры. Прикрутить туда интеграционную шину, ETL-процедуры и т.д., чтобы данные гонялись из одной системы в другую.
2) Разработать единую модель данных для всего предприятия и сделать одну монолитную систему.
Естественно, сначала мы попробовали пойти первым путем, это более логично, чем всё переписать, но быстро надсадились, потому что некоторые ИС использовались просто для распечатки документов, и разработчики не запаривались даже с первичными и внешними ключами. Плюс в принципе тянуть данные из FoxPro - тот ещё гемор. Причём сложно винить разработчиков этих отдельных ИС, ровно по заветам микросервисной архитектуры они выбрали удобные для себя технологии и не тратили время на согласование своей схемы данных со схемами данных других ИС, что позволяло им очень быстро выпускать свои системы в прод, независимо разворачивать их - короче пользоваться основными преимуществами микросервисной архитектуры, хотя тогда этого термина даже и не было.
В итоге мы даже сделали единое хранилище данных, которое наполнялось лютейшими ETL-скриптами, накрутили OLAP-кубы и одну частную задачу построения отчетов решили.
Но потом всё-таки решили, что, нет, нужна единая каноническая модель данных для всего предприятия и одно монолитное приложение. Естественно это существенно упростило и работу ИТ подразделения, и жизнь пользователей, и на порядок увеличило возможности по использованию данных.
Какой из этих двух подходов более правильный и прогрессивный, ну, хз. Конкретно в этом случае для меня микросервисная архитектура - это тот же зоопарк ИС на максималках, который только усугубил бы проблемы. А модульный монолит с единой канонической моделью данных для меня выглядит куда более осмысленным и целостным решением.
Я согласен насчет минусов монолита:
Сложно распределить части приложения между независимыми командами. Хотя, блин, сейчас задумался. А в чём сложность? Стартовый модуль, точка входа в приложение должна быть у всех одна. Но для работы им не нужны все модули. Например, если они разрабатывают модуль для регистратуры поликлиники, то им совершенно не нужен модуль для стационара или аптеки. Достаточно чтобы в приложении была возможность запускать только доступные модули и отключать ненужные.
Сложность масштабирования. Во-первых, на сколько часто эта проблема действительно есть? Во-вторых, разве не проще её решить на уровне СУБД? В том же примере с медицинским центром у нас было несколько распределенных подразделений. В каждом из них просто был развернут свой экземпляр СУБД и данные синхронизировались.
В общем для меня единственный осмысленный сценарий использования микросервисов - это только если каждый микросервис это тупо отдельное приложение, которое практически не пересекается с другими микросервисами. Если у микросервисов разные заказчики, которые планируют использовать данные только из своего микросервиса.
А что если в какой-то момент всё-таки понадобятся целостные данные? Наверное это решится добавлением ещё кучки микросервисов в виде DWH, ETL, ... А что если схема данных в микросервисах на столько разная, что данные фиг соберешь? Это решается с помощью DDD, но тогда это уже не труЪ микросервисы, потому что каждой команде придётся сверяться с единой схемой данных и так быстро фигачить релизы в прод уже не получится.
Короче, я потерял последние доводы в пользу микросервисов. Я реально не понимаю зачем они. Ок, последний довод - это отсутствие единого архитектора на проекте. Хотя, блин, и микросервисная архитектура без архитектора вряд ли обречена на успех. Но наверное этот архитектор должен быть очень ленивый или занятой, чтобы запариваться с единой моделью данных, выбором единых технологий разработки, единой СУБД и т.д. Типа, вот, вам микросервисная архитектура, фигачьте в своих сервисах что хотите, мне пофиг. Ааа, пожалуйста, убедите меня кто-нибудь что это не так и микросервисная архитектура реально решает больше проблем, чем добавляет.
m03r
Тот случай, когда комментарии полезнее статьи. По-моему, эта история может стать отличной статьёй
AnthonyMikh
Так, а вот можно поподробнее про слоты деплоя? Впервые слышу такой термин.
PuerteMuerte
Ещё, может быть, вы слышали "зелёная" и "синяя" среда, или как-то так. Это подход, когда у вас есть две (или больше) сред развёртывания с одинаковой конфигурацией, из которых одна активная в продакшене, остальные неактивны. Вы деплоите в неактивную среду, при этом процесс деплоя никак не влияет на продакшен, после этого единомоментно переключаетесь на новую среду, с новой версией вашего приложения. Если что-то пошло не так, вы точно так же можете единомоментно переключиться на предыдущую, исправную версию. Такой режим деплоя поддерживается облаками, Azure, AWS и т.д.