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

Я, когда спросил разработчика на собесе про микросервисы
Я, когда спросил разработчика на собесе про микросервисы

Когда спрашиваю у людей на собесах, или когда в команде решаем, как клепать очередной проект, такое порой слышу, что становится страшновато. Мне кажется, лет через 5 все компании будут обитать в мультивселенной безумия из “микросервисов”, которую они себе радостно построили, уходя от этих ваших страшных “монолитов”.

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

Что представляют себе разработчики в среднем по больнице

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

Сразу вспоминают про монолиты, что микросервисы это шаг вперёд и вообще гораздо более лучше. На вопросы, а что есть ещё кроме микросервисов и монолитов, отвечают обычно что не знают.

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

  • Можно фигачить каждый сервис на своём фреймворке и языке

  • Проще поддерживать - сервис же маленький, кода мало

  • Проще тестировать - то же самое, сервис маленький же

  • Лучше скейлятся - почему так, и почему эти самые “монолиты” скейлятся хуже, обычно непонятно

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

Как выглядят эти ответы для меня:

Ну или наоборот. Или всё-таки нет.
Ну или наоборот. Или всё-таки нет.

Мало того, что они упускают всю суть, и следовательно начинают лепить “микросервисы” где надо и где не надо, так ещё и делают это плоско, не видя, что никаких “микросервисы vs монолиты” в принципе то и нет, а есть многомерная ситуация в нескольких плоскостях сразу, с кучей выбора.

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

Что важно на самом деле

  • Во-первых, “микросервисы” - это сложно

  • Во-вторых, “монолиты” - это не всегда что-то плохое.

  • В-третьих, индустрия давно уже перешагнула через эту возню “микросервисы vs монолиты”, и воюют уже совсем про другое, но вы ещё не в курсе

С кем воюем

У нас сейчас такой обывательский консенсус, что монолит = плохое зло. 

– Чем микросервисы лучше?

– Чем монолиты конечно

(цитаты королей разработки)

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

“Переписываем монолит на микросервисы”, - говорят и пишут из каждого утюга. Объяснять зачем, уже не модно, и так же понятно - за всё хорошее, против всего плохого, за себя и за Сашку.

Если всё-таки покопаться в сортах монолитов, то на поверхности будет такое:

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

И есть монолиты (про это чуть дальше).

По какой-то совершенно неизвестной мне причине первое часто приравнивается ко второму, хотя это как сладкое и мокрое, вообще разное.

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

Индустрия уже давно впереди

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

  • Модули. Думают, как код разложить на относительно самостоятельные и осмысленные модули / компоненты. Смотрят, где у нас в кодовой базе разные зоны ответственности, и где между этими зонами провести границы.

  • Репы. То есть репозитории и толкание разработчиков в них, чтобы вместе писать там те самые модули, делать в них ПРы, гонять пайплайны и релизить что-то. Можно сделать монорепу и разрабатывать единицы, десятки или тысячи модулей вместе. Можно каждый модуль вынести в свою отдельную репу. Можно сгруппировать по несколько близких модулей в свои репозитории.

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

Про модули

Как и когда разбивать на модули?

Модули нужны чтобы обозначать границы. Границы между чем и чем? Между разными частями нашей предметной области, или как сейчас модно говорить между поддоменами. 

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

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

Получается так. Когда бить на модули:

  • Когда без разбиения на части становится сложно разбираться в коде, большая когнитивная сложность

  • Когда сложно тестировать - например тестов слишком много и они долго выполняются. А гонять надо все тесты при любом изменении. Разбиваем на модули, и если модуль не менялся, то и тесты для него не надо запускать.

  • Когда несколько команд будут работать над разными частями кода. Лучше каждой команде раздать по модулю, потому что очень фигово получается работать, когда много людей толкаются в одних и те же файлах. Постоянно потом конфликты, которые приходится мержить, это долго и больно. И менеджерам сложно трекать, из-за какой команды постоянно баги и откладываются релизы (сарказм, ну или не совсем сарказм ;)). Гораздо проще провести границу между модулями и через эту границу взаимодействовать командам.

  • Когда в коде явно делаются какие-то совсем разные вещи - в одном модуле солим огурцы, в другом управляем грузовиком.

Когда бить ещё рано:

  • Когда вы плохо понимаете, в чём будет ответственность каждого независимого модуля, и где сейчас проходят границы этой ответственности. Можно сначала посмотреть, что там вообще происходит, а потом уже бить на части, когда разберётесь.

  • Когда границы ваших модулей постоянно и довольно сильно меняются. Иначе придётся постоянно эти модули рефачить, двигая границы туда-сюда. Ну и нужны эти границы тогда?

Я мог бы сказать проще - бить надо только тогда, когда уже пора. А если ещё не пора и не видно модулей, то бить не надо. Но бывают сложные ситуации, и там просто сидеть и ждать, когда станет понятно, не сработает. А бывает, что опыта не хватает, и само понимание не придёт. Так что лучше пользуйтесь подсказкой абзацем выше.

Важно: модули - не равно микросервисы. Они не обязаны общаться между собой по HTTP/Кафке, хоть это и можно. Они не обязаны деплоиться отдельно, хоть и можно.

Про репы

У нас 2 крайности - можно или совсем всё держать в одной репе, и будет у нас монорепа, или каждый модуль раскидать в свой репозиторий.

Монорепы

Говорят, сейчас волна хайпа по монорепам прошла, и их уже не форсят так как раньше. Плюс чтобы сделать хорошую монорепу, недостаточно всё сложить в один репозиторий. Нужно ещё классно обмазать всё это пайплайнами, так чтобы у вас был не 1 мега-билд всего, а чтобы артефакты билдились независимо друг от друга и чтобы тесты гонялись отдельно и независимо. И ещё чтобы всё это не толкалось между собой и билды не занимали несколько часов из-за простоя в очереди.

Чего хочет разработчик

Разработчик хочет, чтобы у него всё было в одном окошке IDE, а не в 10, чтобы ему не нужен был для разработки ноут на 64 гига оперативки, и чтоб не надо было переключаться между 5 проектами, чтобы поправить одну багу, а потом создавать и протаскивать 5 ПРов. И ревьюер тоже скажет спасибо, что его не мучают и не заставляют в голове склеивать этот паззл. А сверху на это всё можно написать красивый интеграционный тест и положить его в проект, чтобы можно было его гонять локально, а не ставить задачу автоматизаторам, чтобы подождать несколько дней и потом получать только ночные прогоны этого теста раз в сутки.

Некоторые разработчики считают, что чем больше проектов мы создадим и чем больше окошек IDE у нас будет открыто, тем выше наша крутость, и что это реально зачем-то нужно, для какой-нибудь “поддерживаемости” и “масштабируемости”. Чаще всего ситуация обстоит просто - они не понимают что делают, и это не нужно никому, вот вообще никому.

Когда можно разносить модули по разным репам?

  • Если эти модули редко будут меняться вместе в рамках одной задачи

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

  • Когда репа начинает превращаться в монорепу и требовать нетривиальных усилий на поддержку инфраструктуры билдов

Когда не нужно разносить?

  • Когда мы стартуем новый проект и просто решили, что каждый модуль будет в своей репе

  • Когда мы думаем, что нужно всё сделать “масштабируемо” без понимания сути

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

Про артефакты

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

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

Так вот, если общаться модулям всё-таки надо, а мы их задеплоили по-отдельности, то теперь нельзя просто из одного модуля вызвать метод другого, между ними теперь сеть. И хоба - наша система превращается в распределённую! Со всеми её минусами:

  • Вызвать метод в другом модуле - это теперь долго. Очень долго. Нужно настраивать таймауты, готовить наших клиентов к тому, что наш сервис может отвечать долго из-за сети и доступа к другим сервисам

  • Очень долго - это возможно и никогда. У нас может потеряться сетевая связность между нашими сервисами, или какие-то сервисы могут быть доступны, а какие-то - нет. Часть приложения работает, а часть - нет :) и как нам с этим жить, придётся теперь думать.

  • Всё, что мы хотим передать по сети, надо сначало превратить в текст, типа в JSON например, а потом обратно. Это вообще-то жжёт проц, придётся платить.

  • За траффик тоже придётся платить, так что готовьтесь к разным хакам по его сокращению: 

    • сжатие: о нет, оно тоже жрёт проц! 

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

  • А напоследок самое весёлое - теперь ваша система всегда неконсистентна! Вот этот вот eventual consistency - теперь ваш лучший друг. А ещё:

    • Невозможность атомарно совершать операции. Например, вместо того чтобы в транзакции вызвать метод другого модуля, теперь мы делаем REST-вызов, который не откатится, если наша транзакция упадёт. Транзакции как раньше нам теперь нельзя.

    • Здравствуйте, компенсирующие транзакции!

    • Здравствуй, Saga!

    • Здравствуй, retry!

    • Здравствуй, circuit breaker!

    • Привет, асинхронное общение через очереди!

    • Хай, Dead Letter Queue!

    • Привет, идемпотентность и дедупликация!

    • Здравствуй, exactly once!

    • Здравствуй, transactional outbox!

    • Идемпотентность - наш хлеб и соль!

    • CDC и дебезиум - наше всё!

    • Распределённый сбор логов!

    • Распределенный трейсинг!

    • Распределённый дебаг! (ой, такого у нас нет)

И всё это лишь бы не вызывать один метод из другого.

Кстати, некоторые товарищи пытаются сделать вид, что мы всё ещё типа вызываем метод, просто как бы по сети, но проблемы-то уже обратно не закопать, и абстракции у такого подхода текут будь здоров.

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

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

У вас между микросервисами может течь дурацкий паразитный траффик, который никто специально не порождал, и никто и не знает, что он там есть. Просто в результате бага шлётся не 1, а 2 запроса. И ещё вон там лишний запрос, который можно было и не делать. Это в добавок к тому траффику, который все знают, что он там есть, но тоже нифига не понятно, зачем это было гнать по сети.

Нет, конечно для интеграции между системами это всё тоже нужно, но зачем усложнять себе жизнь внутри нашей же системы, которую пилят 2 с половиной землекопа?

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

Когда может иметь смысл деплоить вещи в разные артефакты?

  • Когда один модуль может грохнуть процесс и утащить за собой все остальные, а нам так не хочется. Например, есть система приёма заказов, и система обработки заказов. Если наша система обработки заказов нестабильна и часто падает по OOM, то это не значит что с ней должна падать и система приёма заказов, это может стоить много деняк. А может и нет. Кто знает. Надо узнавать.

  • Когда мы понимаем, что какой-то модуль нужно будет скейлить в совершенно другом темпе, чем все остальные. Тогда можем подеплоить и скейлить его отдельно. Например, какой-то наш API очень любят другие системы и он очень нагружается, а другие нет.

  • Когда мы хотим вообще другой релизный цикл для модуля - хотим деплоить его много, часто, и версионировать своими версиями, и не хотим, чтобы пришлось в релизы тащить все 50 модулей вместе с ним. 

  • Когда нам нужно использовать другой стек. Внимание: это бывает не так часто, чаще всего компания старается использовать одинаковый стек везде где можно. Например, есть у нас нейросетка, она что-то считает на видяхе, у неё там вообще свой стек, свои либы, своя жизнь. Мы её можем захотеть запускать отдельно, в том месте, где есть мощные видяхи.

  • Ну либо у нас большая система, и какие-то модули поддерживает отдельная команда, Тогда может быть они сами хотят решать всё что описано выше, и пусть решают себе, и дайте им контроль над тем, как деплоится их код, а не мучайте в общем релизе общего артефакта. Или мучайте если уж так хотите, кто я такой чтобы вам тут указывать.

И помните, что всё ещё существуют библиотеки. Это как сервисы, только их можно подключить себе в проект и вызывать их методы напрямую. Разделение есть, а распределённости нет. Хотя это в наши дни почти забытая техника, потому что в микросервисной библиотеки делать особо не принято.

Дак вот, монолиты и микросервисы

Давайте теперь применим наши новые многомерные знания обратно к изначальной теме.

Получается, наш “монолит” - это система, которая разбита на N модулей, которые разрабатываются в 1 репозитории и деплоятся в 1 артефакт - например один docker-образ или war-файл.

А наши “микросервисы” - это по сути те же N модулей, которые разрабатываются в N репозиториях и деплоятся в N артефактов.

И есть же ещё куча вариантов где-то между, этими двумя, где N модулей могут лежать в M репах и деплоиться в P образов. Если вы видите только монолиты и микросервисы, вы не видите кучу вариантов между ними.

Едем дальше. Все эти модули, сервисы - это не статичная херня. Никогда не бывает, что сели архитекторы, придумали как всё будет, потом пришли прогеры, и всё так и написали. А потом ещё 10 лет система жила и всё так и осталось, как было придумано.

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

Например, начинать разработку часто профитно в монолите - 1 репа, N модулей (часто канает по началу даже 1), 1 артефакт. Так быстрее разрабатываем, легче деплоим, нас всё равно в начале мало. 

А дальше никто не запрещает эти N модулей начать деплоить в M артефактов вместо 1. Если вы не нарушали границы между модулями, то просто пошли, обмазали это всё контроллерами или кафкой, поменяли конфиг сборки - и готово.

Если хочется, можно ещё и на P реп это всё разнести. Например когда у нас 3 команды и каждая пилит свои модули, не пересекаясь с другой, и им не хочется видеть ПРы других команд и хочется всё своё и отдельно.

Итого

Вооружившись таким пониманием, теперь вы сможете видеть целых 3 измерения там, где раньше было видно только монолиты и микросервисы. И когда к вам придут и попросят спроектировать архитектуру, вы может быть справитесь чуть лучше и сделаете скорее так, как вам реально нужно, а не так, как выдумает ваше испуганное такой задачей сознание, и принесёте чуть меньше боли и себе, и своей команде, ведь вам же потом с этим жить.

Нам пора уходить от устаревшей и абсолютно непродуктивной дихотомии “монолит – микросервисы” и смотреть на наши конкретные потребности, при этом не стоя сложные распределённые системы начиная с первого дня, особенно там где они изначально не нужны.

И не смотрите на своё решение как на финальное, всё течёт и всё меняется. У вас всё равно не получится сделать хорошо сразу и навсегда. Будьте готовы завтра усложнить там, где будет надо, а не сразу делать сложно, ведь “через год нам это понадобится, когда нагрузка вырастет”. Вы за этот год можете и не закончить ваш мега-микросервисный проект.

Дисклеймеры

Дисклеймер 1: да, язык у статьи простоватый и даже упрощённый, а правила русского языка выборочно игнорируются. Это сделано сознательно, хочу чтобы не звучало душно и люди прочитали, а не заигнорили. Возможно это прочитают и те, с кем я потом буду работать.

Дисклеймер 2: естественно, много всего было упрощено, иначе получилась бы книга. А в чём-то я мог ошибиться. Если это что-то важное, черканите в комменты плз, буду рад узнать что-то новое с вашей помощью.

Дисклеймер 3: как всё на самом деле, я конечно же не знаю, и вы не знаете, и никто не знает. Но все вместе можем предпринять хорошую попытку это выяснить.

Комментарии (132)


  1. Avangardio
    01.07.2024 18:37
    +17

    Отличная статья, но не могу себе не позволить шутку: «Не могу читать монолитные статьи, когда переход на микросервисные».

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

    Лично я нашел имбалансный юзкейс для жс бэкенда: мега io и cpu задачи выкинуть куда-нибудь через Кафку или грпс на гошные инстансы, чтоб не словить случаем блок по загрузке на монолите.


    1. vdudouyt
      01.07.2024 18:37
      +2

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

      Говоря более точно - карго-культ: ЕМНИП все началось с какой-то tech evangelistic статьи, где было написано, что Netflix так делает ))


  1. SergeyPo
    01.07.2024 18:37
    +35

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


  1. 19Zb84
    01.07.2024 18:37

     Думают, как код разложить на относительно самостоятельные и осмысленные модули / компоненты

    Хорошая статья. Спасибо.
    А в двух словах можно, к чему пришли ? Я модули тестирую на js и есть четкое понимание уже, что я хочу и что делаю. Интересно, что на других языках.


    1. Captain_Jack Автор
      01.07.2024 18:37
      +4

      Да вот это и было в двух словах к чему пришёл :)

      Если серьезно, то я из мира java-энтерпрайза, тут если сразу не начали пилить мега-проект на 5 лет, а просто сделали MVP за полгода, это уже считай повезло. Сразу делают "солидно", с замашкой на успешный проект под рост на годы вперёд.

      У нас тут обычно нет практики писать сначала на js, потому что переписывать на другом языке бизнес не готов, когда оно уже работает. Плюс команды не хотят копить техдолг, поэтому сразу делают более менее прилично. Получается правда обычно как всегда :)

      И пожалуй среди джавистов мало тех, кто знает js, а ещё меньше тех, кто любит. Хотя мне в целом заходит.

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


      1. 19Zb84
        01.07.2024 18:37

        Ну это я понимаю )) Не совсем выразился правильно.
        В js сейчас активно модули развиваются.
        Они действительно дают очень большую свободу в написании фронта.
        Начиная с html.

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


        1. Captain_Jack Автор
          01.07.2024 18:37
          +1

          М, вот сейчас понял.

          В java завезли модульность почти 10 лет назад, она даёт хорошую инкапсуляцию. Но она довольно хардкорная и в обычных проектах она не особо используется, больше в каких-то инфраструктурных, где реально важно инкапсулировать часть классов модуля.

          В kotlin тоже есть некоторое подобие - уровень доступа internal. Но тоже пока не встречал, где бы это юзали.

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


          1. 19Zb84
            01.07.2024 18:37

            Понял. Спасибо.
            У js есть особенность. Он асинхронный и модули, что бы могли взаимодействовать между собой их надо синхронизировать между собой и сделать передачу данных в модули, которые может быть ещё не загрузились.
            Плюс надо вокреры(потоки) инициализировать и уничтожить в которые так же надо как то данные из других модулей передавать.

            По этому модули в js имеют, по крайней мере я так вижу, уникальные свойства, которые на языках таких как java сложно увидеть.


          1. SabMakc
            01.07.2024 18:37
            +1

            Подключил как-то на относительно небольшим java-проекте модульность.

            С одной стороны - это было больно. Особенно при работе со сторонними зависимостями - местами пришлось менять зависимости или вообще не добавлять модульность (например, protobuf не сумел подключить в модуль).

            С другой стороны - обнаружил очень много неожиданных связей "вот этого точно локального и никому ненужного класса" и всего остального проекта. Реально было очень много неожиданных открытий. Но разбил, разнес, справился в общем. Главное - модули стали очень четко свою область использования ограничивать.

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

            Так что модульность в java - очень крутая штука. Но к сожалению, редко используемая...


      1. brownfox
        01.07.2024 18:37
        +3

        Сразу делают "солидно", с замашкой на успешный проект под рост на годы вперёд

        Это потому, что в мире энтерпрайза никто не оплатит полугодовой MVP или R&D с непонятным выходом. Там правит бал планирование и KPI :)

        Я сам в прошлом из энтерпрайзной интеграции, Oracle / Tibco / Websphere и прочие "платформенные" истории.


  1. Drucocu
    01.07.2024 18:37
    +2

    Спасибо за статью.

    Любопытно, что не увидел явного упоминания двух страшных слов, вечно сопровождающих такие обсуждения (хоть они и маячат между строк): связность и запутанность)

    Артефакты. Артефакты бывают разные, но в целом это те штуки, которые мы релизим.

    Это точно устоявшийся термин? Почему-то мозг об него буксует.


    1. Captain_Jack Автор
      01.07.2024 18:37
      +4

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

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

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

      Это точно устоявшийся термин?

      Вряд ли, написал как понимаю, больше из головы. Тоже думаю, что здесь как-то нечётко вышло.


    1. AntonLarinLive
      01.07.2024 18:37
      +18

      Артефакты. Артефакты бывают разные, но в целом это те штуки, которые мы релизим.

      Это точно устоявшийся термин? Почему-то мозг об него буксует.

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


      1. panzerfaust
        01.07.2024 18:37
        +16

        Не знаю как в дотнете, но в джаве Apache Maven использует понятие "артефакт" испокон веку. Да и в нексусе оно так называется. Или вшито в название как в JFrog Artifactory.


        1. Proscrito
          01.07.2024 18:37
          +3

          В дотнете также. Артефакт(ы) - результат билда. Имеет определенную версию. При деплое артефакты копируются в нужные локации. Устоявшийся термин. Настолько устоявшийся, что даже удивился вопросу) Очевидно, что не везде он устоялся.


    1. RH215
      01.07.2024 18:37
      +7

      Это точно устоявшийся термин? Почему-то мозг об него буксует.

      Да, термин уже достаточно давно существует в CI. Например в Gitlab:
      https://docs.gitlab.com/ee/ci/jobs/job_artifacts.html


      1. Drucocu
        01.07.2024 18:37
        +1

        Кажется, вы его не понимаете.

        В приведённом примере - это объект, полученный в результате работы job'ы. То есть "то, что осталось" - это буквальное значение слова "артефакт".

        Автор же использует артефакт в смысле "единица деплоя" (подсмотрел в комментах).


        1. swingaroo
          01.07.2024 18:37
          +6

          Что одному единица деплоя, то другому -- результат сборки. И тут слово "артефакт" -- "искусственно сделанный", вполне уместно.
          PS. То, что осталось - это реликвия.


          1. Drucocu
            01.07.2024 18:37

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


            1. xxxDef
              01.07.2024 18:37
              +4

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


        1. zaiats_2k
          01.07.2024 18:37
          +1

          Нет, не то что осталось, а from Latin arte ‘by or using art’ + factum ‘something made’, извините.


          1. Nashev
            01.07.2024 18:37
            +1

            Это ж "Произведение искусства", если по-русски дословно. Забавно!


            1. Flammar
              01.07.2024 18:37
              +1

              То, что в классах члены-функции называются "методами", т.е. по-русски "путями через", вас не смущает?


              1. Nashev
                01.07.2024 18:37

                Тоже забавляет, ага. И то и другое вполне меткие метафоры.


  1. kenomimi
    01.07.2024 18:37
    +20

    Монолит - это когда всё приложение для бухгалтерии ТНК - один полуторагиговый жарник (без ресурсов, да - ресурсы отдельно). Запуск на вебсфере около часа. Да, внутри все разложено на модули, но это монолитная дура, запускающаяся последовательно. Если оно наворачивается - а сделать ООМ элементарно легко загрузкой любой разновидности зип-бомбы, или просто файла с кинцом на полтерабайта... Там под капотом решение третьей стороны, крупного американского вендора, которое класть файлы в свое пропиетарное хранилище стримом не умеет, только подняв файл в память полностью. Баги были заведены, но отклонены с каментом "не баг, а фича". Плюс тысяча конвертеров документов, анализаторов, преобразовалок... Навернулась нода - жди час перезапуска. Нод 50, но пользователь упрям, и продолжает грузить этот злополучный файл - половину кластера ложит легко. Сборка - два часа в мемдиске, на хардах полдня, локально не запустишь - дай от терабайта оперативки. Вот это монолит.

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

    Еще есть наносервисы - приложение с одной единственной функцией и девизом "пох на падения" :) чаще всего это приложения, конвертирующие доки либо работающие с архивами. Пошла утеча памяти или распаковка сожрала всю оперативку? Контейнер убивается, тут же запускается новый. Заддосить почти нереально. Минусом будет тот факт, что когда наносервисов станет много - начнется ад коммуникации, запомнить какой топик в кафке чей и кто использует - не очень реально. Хорошо, если есть культура идеального документирования, но почти всегда ее нет, увы.

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


    1. gravyzzap
      01.07.2024 18:37
      +41

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

      Это про говнокод, а не про монолит. Решается оборачиванием решения под капотом собственным кодом, который проверяет размер файла.

      stateless

      Как микросервисность делает ваше приложение стейтлес? Или вы имеете в виду, что некоторые микросервисы будут стейтлес?

      и так же быстро откатить

      Попробуйте откатить баг в микросервисе А появившийся три версии назад, с которой не совместимы последние 5 версий сервиса Б, с которыми несовместимы последние 10 версий сервиса В. Депенденси хел цветёт и пахнет в микросервисах.


      1. maxzh83
        01.07.2024 18:37

        Попробуйте откатить баг в микросервисе А появившийся три версии назад, с которой не совместимы последние 5 версий сервиса Б

        А как это связано, если баг не задействует контракт между сервисами А и Б?


        1. Virviil
          01.07.2024 18:37
          +10

          Починить баг - можно. Откатить - нельзя. Потому что наверх написаны коммиты которые задействуют контракт между сервисами A и B


          1. maxzh83
            01.07.2024 18:37

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


          1. Didimus
            01.07.2024 18:37

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


      1. vvbob
        01.07.2024 18:37
        +5

        Это про говнокод, а не про монолит. Решается оборачиванием решения под капотом собственным кодом, который проверяет размер файла.

        + перехват исключений, на тот случай если что-то не предусмотрели. Поймали непонятное исключение в котроллере, записали в лог инфу о нем, отдали 500, продолжаем работать.

        ИМХО, микросервисы это такая шляпа, которую надо по возможности избегать, юзать их надо только тогда, когда без них никак не обойтись (процентов в 95% всех проектов, которые у нас делают на микросервисах можно и нужно было делать монолитом)


      1. Proscrito
        01.07.2024 18:37
        +4

        Все верно. Депенденси хелл, повышенные требования к архитектору, к девопсам, повышенная сложность интеграционного тестирования, накладные расходы в связи с кап-теоремой, больше ресурсов на холодную систему. Это все плата за возможность независимо скалировать отдельные части системы и повышенную отказоустойчивость. Платить, или не платить - надо считать. Хорошо, если есть тот, кто считать подобное умеет. Для бизнеса хорошо.


    1. Xexa
      01.07.2024 18:37
      +17

      Микросервисы - это быстрый рестарт, stateless, и возможность сделать больше инстансов того приложения, где вероятны отказы 

      Ага. Щас.

      С чего такое мнение? Через задницу написанный код хоть замикросервисируйся - стартанёт когда стартанёт и то если повезёт и не будет взаимной зависимости кольцевой.

      Не помогут микросервисы. Не помогут. Если хватит квалификации написать их, то и на монолите у этого же человека(команды) не будет проблем.


      1. tuxi
        01.07.2024 18:37
        +1

        Там еще вишенка на торте, девопсы под тонну микросервисов, у которых иногда "волосы шевелятся в самых неприличных местах"


      1. Fireball222
        01.07.2024 18:37

        Ну вот если квалификации недостаточно, то микросервисы здесь могут помочь. Так, не очень опытный сотрудник сможет "развалить" только один сервис. Еще кстати в микросервисах сложнее привносить неявные зависимости между модулями, в монолите всегда есть возможность срезать углы, нареференсать каких-нить внутренних классов из другого модуля и вот это все.


  1. brownfox
    01.07.2024 18:37
    +16

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

    Монолитная организация исполняемого кода, модули, микросервисы, взаимодействующие процессы, паттерны и т.п. - это инструменты, которые необходимо применять с умом и на благо. И только то :)

    Ноги у популярности микросервисов, разумеется, растут из веб-программирования, как и многие другие не совсем адекватные вещи. За последние годы я не раз сталкивался с последствиями такого подхода, разгребая чужие legacy-решения. В одном случае автор для решения достаточно простой задачи нагородил 6 микросервисов с отдельными БД (да-да, есть ещё секта противников "монолитных" баз). В другом программа просто не работала в контуре заказчика, изолированном от интернета, потому что "ну всегда же можно указать ссылку на фреймворк".

    Так и живём.


    1. Captain_Jack Автор
      01.07.2024 18:37
      +8

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

      Сам делал так же, пока не разобрался в теме. Помню как один раз вкорячил 4 сервиса там, где прекрасно работал бы и 1, потом пришлось переделывать.

      Поколение новичков, выбирающих по наитию, никогда не иссякнет, но надеюсь, что хотя бы пройдет этот консенсус в индустрии, что делать микросервисы - это стильно-модно-молодёжно, и вообще уйдет эта ложная дихотомия "монолиты против микросервисов". Может тогда будет меньше ориентира на хайп. Хотя кого я обманываю :)


    1. persona
      01.07.2024 18:37
      +6

      6 микросервисов с отдельными БД (да-да, есть ещё секта противников "монолитных" баз)

      Но микросервис же обычно подразумевает использование своей БД, куда только этот микросервис имеет доступ. Иначе зачем тогда этот микросервис нужен?


      1. brownfox
        01.07.2024 18:37
        +4

        Иначе зачем тогда этот микросервис нужен?

        Нужен он для выполнения некоторой относительно простой функции, как обычно и заявляется в концепции микросервисов :)

        Микросервис не требует наличия собственной БД, он может вообще не обращаться к базе или работать с отдельной схемой централизованной БД. Или даже без отдельной схемы.

        Разделение данных по владельцам с их передачей через API - совершенно отдельная идея, родившаяся, IMHO, в головах людей, которые не понимают, как готовить Оракл озабоченных в большей степени производительностью сервисов на выдачу данных. Распределение информации по кэшам в виде микросервисных БД именно эту проблему решает.

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


        1. persona
          01.07.2024 18:37
          +3

          Конечно микросервис может не использовать никакую БД, я подрузамевал что если она нужна.

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

          В целом тогда нужно проводить разделение между сервисами и микросервисами в составе сервиса. Сервис должен владеть своими данными. Микросервисы могут соответственно могут шарить общие данные. Но другие (микро)сервисы могут иметь доступ к данным этого сервиса только через его API, без прямого доступа к данным.


          1. brownfox
            01.07.2024 18:37
            +1

            Сервис должен владеть своими данными

            Сервис - да. Вообще, очень полезно, когда разработчик понимает, для чего именно используется в системе тот или иной подход, какие плюсы и минусы он даёт на этапе разработки и эксплуатации. А архитектор прямо таки обязан это понимать.

            API, кстати, тоже не обязан сводиться к HTTP/REST, в принципе, это может быть что угодно, хоть XML, доставляемый на собаках :)


          1. RH215
            01.07.2024 18:37

            Сервис должен владеть своими данными. Микросервисы могут соответственно могут шарить общие данные.

            Абсолютно прекрасное определение, но кто ж его продвинет в массы.


      1. Flammar
        01.07.2024 18:37

        Иначе зачем тогда этот микросервис нужен?

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

        С БД там в общем случае сложная засада — тоже оформлена как отдельный "слой", работа тоже через балансировщик, запись и чтение разделены настолько, что нет гарантии, что то, что записал, тут же сможешь прочитать (вместо предыдущей версии данных), "транзакции на уровне бизнес-логики" устаивать трудно. Логику приложения необходимо строить исходя из этого обстоятельства, что может взрывать мозг.


    1. tuxi
      01.07.2024 18:37

      То есть ему пришлось разворачивать бекап 6 баз данных вместо одной? И потом кому то мониторить все это?


    1. Proscrito
      01.07.2024 18:37
      +4

      Да, я большой противник монолитных баз. Если вам нужна монолитная база - вам не нужны микросервисы. И да, очень часто сегодня их используют там, где они не нужны. Либо их намного больше, чем реально нужно. Но если они действительно нужны, они должны быть полностью независимы, включая источники данных. Никак иначе. Одна база на 2 микросервиса - красный флаг пересмотреть архитектуру. Если вам кажется, что 2 сервиса обязаны иметь одну базу - смело объединяйте их в один. Если вы твердо решили разделить сервис на 2 и более - сразу решайте как разделить базу. Причем в первую очередь. Если выходит плохо - см. пункт 1.


      1. brownfox
        01.07.2024 18:37
        +1

        У вас прямо какое-то религиозное отношение к вопросу о базах микросервисов.


        1. Proscrito
          01.07.2024 18:37
          +1

          Да, возможно. Как к принципам солид, или драй. В целом можно нарушить, но если нарушение обнаружено - нужно семдесят семь раз перепроверить, не случилось ли фигни.


        1. Kano
          01.07.2024 18:37
          +2

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


      1. xxxDef
        01.07.2024 18:37
        +4

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


        1. Proscrito
          01.07.2024 18:37

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

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


  1. sse
    01.07.2024 18:37
    +3

    "Можно писать на любом языке" и "2-pizza team" это все selling points для недоверчивых технарей, а я расскажу, почему на самом деле бизнес выбирает микросервисы. Причин всего две:

    1. Быстрая проверка гипотез, которые в 9 из 10 случаев проваливаются - да, продакт-менеджеры тоже не боги. В случае монолита вы стоите перед непростым выбором: или вкладываться по полной в эксперимент (дизайн, код, тесты), который, скорее всего, будет выброшен, или на коленке слепить то, что рискует выстрелить, и тогда с этим поделием придется жить вечно в монолите. Какой вариант хуже? Оба хуже. В случае с микросервисами эксперименты не сильно трогают ядро системы, которая кормит всю компанию и их семьи.

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

    Эти две причины пересиливают (как будто бы) все сложности, связанные с МСА. А сложностей немало, от оркестрации до смены парадигмы владения системами.

    Все, кроме этих двух причин на самом деле ни зачем не надо. А, еще маленькое замечание: проще нанимать людей, потому что "у нас такие же крутые технологии, как в Гугле (так что мы будем платить поменьше)".


    1. Drucocu
      01.07.2024 18:37
      +4

      Быстрая проверка гипотез

      Решается не микросервисами, а специальными инструментами: будь то отдельная инфраструктура для AB-тестирования или feature toggle. То же самое может быть организовано и в монолите. По вашему что, под каждую гипотезу пишется свой микросервис, а потом дропается?

      в случае микросервисной архитектуры можно нанимать вообще любых программистов

      у нас такие же крутые технологии, как в Гугле (так что мы будем платить поменьше)

      Какие-то влажные фантазии. Наверное, поэтому зарплаты Golang (основной язык для этих ваших микросервисов) в ТОП-5 на бекенде?

      Кажется, ваш обидел какой-то адепт микросервисов и вы теперь вымещаете зло на всех. Не стоит: человек может быть просто не очень, независимо от того, на чём пишет.


      1. Didimus
        01.07.2024 18:37

        Разве на java основной язык ещё?


    1. xxxDef
      01.07.2024 18:37
      +3

      Никогда не понимал этого "можно нанимать любых программистов потому что у нас микросервисы". Сегодня наймем джависта, завтра дотнетчика, а послезавтра питониста. А кто весь этот зоопарк потом подлерживать будет? Или микросервисы - это всегда write-only код?


      1. Gromilo
        01.07.2024 18:37
        +3

        найти хорошего разработчика за праздник

        Любой программист - это про уровень навыков. Тут как-то чувак жаловался на яндекс, что понаделали микросервисов в которых 80% кода генерируется тулами, а 20% пишет кто угодно по контракту аналитиков. Типа там они платят меньше и легче заменяют программистов.

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


      1. Nashev
        01.07.2024 18:37
        +1

        Дык, у них write-only  - основное рекламное преимущество, похоже. Чтоб не влом было любой взять и целиком переписать за вменяемое время на любой новой технологии. Но так никогда не получается, ИМХО.


        1. Flammar
          01.07.2024 18:37
          +1

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


  1. tuxi
    01.07.2024 18:37
    +8

    Спасибо что не побоялись сказать то, что у многих уже накипело.


  1. sergey_prokofiev
    01.07.2024 18:37
    +7

    Самый важный аспект упустили: микросервисы deploy fast. Это и хорошо и плохо.

    Допустим, у вас продукт, над которым работают 5 команд, каждая отвечает за свой модуль/микросервис. Одна команда сделала синюю кнопочку зелененькой и менеджмент хочет прям завтра видеть ее зеленой на проде, потому что поднимет продажи, конверсию все дела. Если выкатим послезавтра - потеряем миллионы, а менеджер годовую премию.

    В случае монолита очень сложно сделать быстрый релиз: ведь в той же единице деплоймента(монолит) находятся текущие изменения остальных 4х команд. Соотвественно, во первых надо согласовать со всеми что код готов к выкатке, во вторых сделать полную регрессию чтобы убедиться что все таки работает. И затем выкатить. На завтра не получится никак, ну или тестеров наручниками к батарее на ночь.

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

    Аналогично, облегчается задача 0-downtime deployment для асинхронных воркеров: в ряде случаев их можно передеплоивать с даунтаймом, при условии гарантированной доставки им сообщений.

    Но весь этот прекрасный мир работает до тех пор, пока нет изменений в контрактах между микросервисами.

    В случае с монолитом все внутренние контракты входят в одну единицу деплоймента, соотвественно поменяли, задеплоили.

    В случае с микросервисами, это не так. У каждого микросеврсиа свой релизный цикл. И если команда А поменяла контракт, то у команды Б(которая вызывает микросервис команды А), свои планы, свои задачи и тд. У команды В, которая тоже дергает микросервис команды А - своя история. И на практике команде А надо поддерживать 2 версии контракта, старую и новую, пока клиенты не перейдут на новую. Это может занять время, и новое изменение контракта уже в планах... 3 версии....

    There is no silver bullet к сожаление.


    1. janvarev
      01.07.2024 18:37
      +3

      В случае монолита очень сложно сделать быстрый релиз: ведь в той же единице деплоймента(монолит) находятся текущие изменения остальных 4х команд.

      Но весь этот прекрасный мир работает до тех пор, пока нет изменений в контрактах между микросервисами.

      Все просто - если у вас хорошие контракты - либо между модулями (монолит), либо между сервисами (микросервисы), то вы можете деплоится быстро и независимо - потому что дотестировать изменение контрактов не нужно. Монолит пересобирается с обновленными модулями/библиотеками, сервисы выкатываются и перезапускаются.

      А если у вас контракты постоянно меняются, то проблемы будут что на монолите, что на микросервисах.

      В любом случае упор в качественную архитектуру с хорошей изоляцией и контрактами.


      1. sergey_prokofiev
        01.07.2024 18:37
        +1

        потому что дотестировать изменение контрактов не нужно

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


        1. janvarev
          01.07.2024 18:37

          Текущая версия монолита пересобирается с обновленными библиотеками (которые пилятся разными командами как раз) и деплоится.


          1. sergey_prokofiev
            01.07.2024 18:37
            +1

            Тогда надо делать полную регрессию, это вам любой QA скажет.


            1. janvarev
              01.07.2024 18:37
              +3

              Что мне скажет QA, меня мало интересует. Меня интересует, будет работать или нет.

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

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


              1. sergey_prokofiev
                01.07.2024 18:37
                +5

                Что мне скажет QA, меня мало интересует. 

                Я думаю что ваше мнение мало интересует ПМ-а, который рулит разработкой 5 команд. У него банально нет времени идти в код и смотреть историю мерж реквестов, нарушились ли контракты или нет. За качество отвечают QA и именно их будут спрашивать какие тест сеты надо заранать.

                Если меняются контракты - что монолит, что микросервисы склонны к проблемам из-за некогерентности

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


                1. janvarev
                  01.07.2024 18:37
                  +2

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

                  Ну, вот с этим согласен, да. Поэтому я в своей собственной практике больше на монолит с модулями опираюсь ))

                  А так, конечно, по-любому нужен QA, вне зависимости от способа разработки софта.


                  1. sergey_prokofiev
                    01.07.2024 18:37
                    +1

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


                    1. janvarev
                      01.07.2024 18:37

                      И есть недостатки - высокая инженерная культура в компании и хорошо налаженный процесс.

                      Согласен, это под хороших инженеров отличный воркфлоу.

                      С распределенными под сотню человек дела не имел, и подозреваю, что да, там другие проблемы, и пусть закрываются задачи хотя бы на отдельных сервисах (откуда и любовь к сервисам)


                      1. sergey_prokofiev
                        01.07.2024 18:37
                        +1

                        Согласен, это под хороших инженеров отличный воркфлоу.

                        И идеальные менеджеры :)

                        С распределенными под сотню человек дела не имел

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


    1. Drucocu
      01.07.2024 18:37

      в той же единице деплоймента

      @Captain_Jack, тут хорошая формулировка, как мне кажется.


  1. mivlad
    01.07.2024 18:37
    +2

    А дальше никто не запрещает эти N модулей начать деплоить в M артефактов вместо 1. Если вы не нарушали границы между модулями, то просто пошли, обмазали это всё контроллерами или кафкой, поменяли конфиг сборки - и готово.

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


  1. panzerfaust
    01.07.2024 18:37
    +13

    По какой-то совершенно неизвестной мне причине первое часто приравнивается ко второму, хотя это как сладкое и мокрое, вообще разное

    Это называется плохая репутация.

    У нас тут на хабре олды с 20+ лет опыта любят рассказывать, как божественно они писали 10-15 лет назад. А мой личный опыт таков, что самый всратый код - это как раз с культурного слоя "конец нулевых, начало десятых" и написан он нынешними архитекторами и си-грейдами. Причина проста: не хватало еще коллективного опыта плюс над ними не было старших товарищей с этими же 20+ годами. Если говорим про джаву, то в нулевых годах это был еще молодой язык с растущей экосистемой. Писали кто во что горазд.

    Следующее поколение пришло, взглянуло на эту хтонь, ужаснулось и выработало ассоциацию "монолит == говнокод, только микросервисы, только хардкор". Говнокода в микросервисах тоже хватает, но опять же по моему опыту, работать с ним не настолько больно. Потому что у этого поколения уже есть опытные старшие товарищи с живительным подзатыльником.

    Новое поколение приходит и видит данную дискуссию монолит vs микросервисы. Надеюсь, они будут допускать еще меньше идиотских ошибок.


    1. tuxi
      01.07.2024 18:37

      Не бывает абсолютно идеальной архитектуры. И близкой к идеальной не бывает. Идеальность всегда завязана на текущие доступные вычислительные ресурсы / сетевые возможности. Java середины-начала нулевых (да, я оттуда) это весьма некислые цены на выделенные сервера и толщину канала. И если стоит задача обеспечить 300...500 rps при достаточно сложных требованиях от бизнеса, то будет использована именно та архитектура, которая это обеспечит.


    1. Drucocu
      01.07.2024 18:37

      Вы в целом описали как эволюционирует наша индустрия. Плохо, что ли? Хорошо.


    1. sshikov
      01.07.2024 18:37
      +1

      Ну не 10-15, побольше. А точнее даже, дело вообще не в годах.

      В 2005, т.е. почти 20 лет назад, вокруг меня были вполне устоявшиеся коллективы с приличным коллективным опытом.

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

      Само же предположение о репутации... оно вполне валидное.


      1. FlyingDutchman2
        01.07.2024 18:37

        В 2005, т.е. почти 20 лет назад, вокруг меня были вполне устоявшиеся коллективы с приличным коллективным опытом.

        Да и в 1990-х были. Примеры: авиакомпания KLM или голландская государственная телефонная компания KPN Telecom.


        1. sshikov
          01.07.2024 18:37
          +2

          Так я примерно про это. 10-15 лет назад все было так же, как и сегодня. Был говнокод, и были сложившиеся команды.


    1. xxxDef
      01.07.2024 18:37
      +1

      "если тебе нравиться твой старый код, значит все это время ты не развивался" (с) не помню


  1. SellerOfSmiles
    01.07.2024 18:37

    Мало нам было разработчиков которые спорят как нужно правильно писать код вместо того чтобы хоть что-нибудь написать. Так теперь ещё об'явились не_разработчики (судя по посылу) которые указывают разработчикам как им правильно думать на тему (и без), и о чем теперь модно спорить...


  1. amazingname
    01.07.2024 18:37
    +1

    Вот эти два пункта ИМХО и есть основная причина по которой нужны микросервисы:

    • Когда мы хотим вообще другой релизный цикл для модуля - хотим деплоить его много, часто, и версионировать своими версиями, и не хотим, чтобы пришлось в релизы тащить все 50 модулей вместе с ним. 

    • Ну либо у нас большая система, и какие-то модули поддерживает отдельная команда, Тогда может быть они сами хотят решать всё что описано выше, и пусть решают себе, и дайте им контроль над тем, как деплоится их код, а не мучайте в общем релизе общего артефакта. Или мучайте если уж так хотите, кто я такой чтобы вам тут указывать.

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


  1. kai
    01.07.2024 18:37

    Когда у тебя несколько монолитов. Они становятся микросервисами. Автор, конечно, смешал в кучу всё на свете.


  1. ggo
    01.07.2024 18:37
    +5

    В целом с большинством тезисов согласен.

    Только один комментарий. Микросервисы - это не про технологии, микросервисы - это про бизнес, про способ организации работы большого количества разработчиков. И основной значимый критерий сервис микро или нет - одна ИТ команда (5-7 человеков) полностью отвечает за сервис, от разработки до сопровождения. Работает плохо этот сервис? Только эта команда его чинит.

    Является ли микросервис - подой в кубере или OSGI-модулем в большом java-приложении - в общем случае неважно. Хотя в экстремуме микросервис должен обладать своими собственными ресурсами, которые никакой другой сервис забрать не может.


    1. Didimus
      01.07.2024 18:37

      Одна команда может пилить несколько микросервисов.


      1. ggo
        01.07.2024 18:37

        легко


  1. dezahrise
    01.07.2024 18:37
    +2

    Вот тут 1 момент упущен. 90% предприятий, 60-70% занятости и 50% ВВП во всем мире приходятся на долю мелких и средних предприятий. А там никакой дискуссии нет - практически 1 монолит.


    1. Yuriy_75
      01.07.2024 18:37

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

      А вот если 100 человек "пилят монолит" - тут можно и сачкануть, все равно никто не заметит.


  1. SnowBearRu
    01.07.2024 18:37
    +1

    Я бы еще в статье упомянул https://ru.wikipedia.org/wiki/Сервис-ориентированная_архитектура вот это. На мой взгляд это завязано темой.

    Это как раз тот самый модульный подход в общем случае.


  1. Mr_Cheater
    01.07.2024 18:37

    Извините, может, я невнимательно прочитал или просто не понял. А модули разве не обладают теми же недостатками, что и микросервисы?

    Ну, например, те же зависимости - в js, хотя бы.


    1. Captain_Jack Автор
      01.07.2024 18:37
      +2

      Модули и микросервисы отличаются одной вещью точно - микросервисы вынуждены общаться по сети со всеми вытекающими, а модули нет.

      Ещё микросервисы обычно имеют независимый релизный цикл, а модули могут релизиться все вместе.

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

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


      1. Kano
        01.07.2024 18:37
        +1

        Наверно всё же микросервис это изолированная часть бизнес логики которая реализует некий публичный контракт для взаимодействия с другими частями системы. По сути приставка "микро" определяет объём реализуемого контракта. Степень изолированности это условность, которая может быть выполнена как на уровне датацентров так и внутри одного процесса и она определяет механизмы взаимодействия между частями системы (по сети или как то иначе)


        1. xxxDef
          01.07.2024 18:37
          +2

          Забыли добавить - "в реальности не встречается"


    1. Cerberuser
      01.07.2024 18:37

      в js, хотя бы

      В любом языке с динамической (а тем более слабой) типизацией - да. А в языке с типизацией уровня хотя бы Java/Go - во многих случах проблемы с зависимостями детектируются заметно быстрее (в худшем случае - во время сборки перед деплоем), а соответственно, и правятся проще.


  1. MarijQA
    01.07.2024 18:37

    Вот бы и тот, с кем мне ещё работать, тоже эту статью прочитал!

    Бывало пару раз... идёшь на проект, спрашиваешь о нюансах архитектуры, а тебе - микросервис. Приходишь, начинаешь работать, а там монолит с модулями...просто почему-то пиэм вообще не в курсе разницы. Для него монолит - это как лендинг. Если есть модули, знач, уже микросервис. Я не разработчик, но мне как-то немножко обидно было))))

    Мне про противостояние монолитов и микросервисов ещё никто так круто не рассказывал. Мне - потому что стиль публикации,хоть вы и указали на упрощеность языка, очень толковый. Создаёт ощущение разговора один на один. Точнее - вы говорите, а я смотрю и слушаю. Очарована и почти влюблена.


  1. ScyberG
    01.07.2024 18:37

    Довольно обширно расписано, спасибо за проделанную работу. Интересно было почитать! Заметен опыт практики в вопросах применения разных подходов.


  1. Kerman
    01.07.2024 18:37
    +2

    hibernate ORM, который в фоне заваливает базу миллионом ненужных вам запросов

    Непонятно, за что гибернейту досталось. Он же не AI, он сам запросы не выдумывает. Если у вас миллион запросов в фоне от гибернейта, значит где-то миллион запросов в фоне к гибернейту.


    1. Gromilo
      01.07.2024 18:37

      Я так понял речь о том, что хватило 10 запросов, а ORM по какой-то причине делает 30. И мы этого не видим. Правда мы этого не видим и когда руками запросы делаем. Кто может поручиться, что у него точно нигде нет N+1 запроса?


      1. Kerman
        01.07.2024 18:37
        +1

        У меня много вопросов к гибернейту. Например, почему eager/lazy указываются в модели, когда мне для решения вот этого N+1 надо пару раз eager, а потом мне не надо лишний джоин. Почему нельзя было ситуативный выбор сделать, как в EF? Или почему нельзя в полях одновременно получать сам объект и его ID. ID же лежит в колонке, вот он. Ан нет, либо крестик, либо трусы.

        Там ещё заморочка была с композитными ключами, сейчас не помню...

        Много вопросов, много. Но как-то цепляет, когда его обвиняют в самостоятельной генерации спами в БД.


    1. Captain_Jack Автор
      01.07.2024 18:37

      Нууу... и да, и нет. Запросы он всё-таки генерирует сам под капотом. Например, мы в коде пишем post.getComments().get(1), а в фоне у нас генерируется и выполняется запрос в БД на получение первого коммента.

      Конечно же hibernate не виноват, что всё в итоге тормозит. Но имеем что имеем, иногда чтобы исправить такие проблемы, приходится в сервисе вообще всё взаимодействие с БД рефакторить.

      Опять же, нужны знания, чтобы эффективно пользоваться инструментом, и не пользоваться им там, где не надо. Я на собесах бывает спрашиваю, где hibernate использовать не стоит, и очень редко люди это понимают.


      1. Kerman
        01.07.2024 18:37
        +1

        То есть претензия к тому, что гибернейт выполняет запрос в БД, когда вам нужны данные из БД?

        Или к тому, что слишком сильно упрощается доступ к БД и котята не понимают, что они лезут в базу, а не в прощающий всё List<T>? Так вроде ORM для этого и нужен.


      1. panzerfaust
        01.07.2024 18:37
        +3

        В 2024 году актуальный вопрос это на кой его вообще хоть где-то использовать.


        1. Captain_Jack Автор
          01.07.2024 18:37

          А что его нишу сейчас заняло?

          Spring Data JPA же на нём работает, и спринг сейчас очень много где.


          1. panzerfaust
            01.07.2024 18:37
            +1

            Не сказал бы, что прям кто-то занял. В вакансиях хибера полно. Просто это артефакт из времен, когда модно было оверинжинирить. Его авторы пляшут от предположения, что разработчик боится SQL. Чтобы спасти несчастного, они накурили оверхед. А потом Pivotal еще сверху своей спринговой черной магии бахнули. А я в общем-то не боюсь SQL. Мне нравится самому писать запросы и думать над их оптимизацией.

            В общем случае для своего условного нового сервиса я возьму JOOQ. Если много аналитических запросов, то MyBatis. Если упарываться по Kotlin, то можно Exposed попробовать. Нафига мне эти хибер и спринг дата, я просто не знаю.


            1. Kerman
              01.07.2024 18:37
              +1

              Так жук это тот же самый ORM. У него есть свой собственный язык запросов, который транслируется в SQL. И точно также он не покрывает все нюансы SQL и точно также не должен. Фрукт-фрукт.

              Про MyBatis уже был спор с кем-то. Утверждали, что он не ORM. Ну да, он просто маппер.

              Нафига вам спринг дата я не знаю. Она и мне, если честно не нужна, вместе с жавой. Шарп как-то вкуснее мне оказался. Но то, что есть большая проблема управления сложностью в больших проектах - это факт. Внедрение ORM хорошо помогает с ней справиться, отделяя слой работы с БД от бизнес-логики. Для меня ещё очень важно, что полностью исключаются ошибки маппинга.


    1. sshikov
      01.07.2024 18:37

      Если он сам разбирается в связях 1:М или M:M, он таки выдумывает запросы, что бы это ни значило. Просто его API - он не настолько гибкий (ну если не считать написания SQL самому) чтобы он их выдумал не просто правильно, но и всегда эффективно.


      1. Kerman
        01.07.2024 18:37

        Так задача ORM - это маппинг сущностей в первую очередь. Если вы ожидаете от него покрытие всех возможностей генерации SQL, то зря. ORM вообще не про это. В моей ORM вообще можно было через LINQ генерить запросы, а если мало - пиши ручками SQL, орм просто замапит результат.

        В типах связей ORM обычно разбирается. Тут нет ничего сложного - есть PK, есть FK на другую сущность. Обычно из этой информации следует единственно возможный вариант джойна.

        ORM хорош для 95% запросов, где дальше джойна и простого WHERE ничего не надо. То, что остальные 5% запросов больно делать через ORM не значит, что ORM не нужен


        1. sshikov
          01.07.2024 18:37

          Так я не говорил, что он не нужен. У меня были проекты, где я его использовал, и были где писали на голом SQL, и вообще ничего никуда не мапили.

           есть PK, есть FK на другую сущность

          Ну к сожалению не всегда. Видел кучку проектов, где не было ни FK (что еще бы ладно), ни даже PK.


          1. Kerman
            01.07.2024 18:37

            ни даже PK

            Я вызываю полицию!


            1. sshikov
              01.07.2024 18:37

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


              1. Kerman
                01.07.2024 18:37
                +2

                Не, не зря. В спецификации той же MySql написано, что корректная работа без PK не гарантируется. Подозреваю, что у всех остальных так же.

                Логи записывать в БД - это ещё один повод вызвать полицию. Вот зачем? Есть же тот же самый NLog и ещё куча решений. Выборка логов нужна примерно раз в никогда лет. Ротация нужна по переполнению. БД это тупо не умеет. В файловых логах это мало того, что проще, так ещё и меньше диска занимает и можно выделить хранилище как раз для данных такого рода ценности.

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


                1. sshikov
                  01.07.2024 18:37

                  Нет апдейта, нет делита, просто потому, что не за что зацепиться.

                  Ну я же вроде ясно написал - логи аудита (или не написал что аудит?). То что у вас в аудите нет удаления и обновления - это плюс, а не минус. Ибо нефиг обновлять документ.

                  Ротация нужна по переполнению. БД это тупо не умеет. 

                  Все практические случаи что я видел, были партиционированы. Это в общем все, что от них как правило нужно (храним N лет по требованиям регулятора, через год сбрасываем на ленту партиции, и все). И это были ораклы и MS SQL, так что две эти СУБД вполне нормально работают с такими таблицами (объемы - терабайты). MySQL же в моем мире встречался один раз, и я бы сказал, что многовато у него своей специфики, чтобы считать его эталоном.

                  Ну то есть, я в целом скорее согласен, что решение странное (практически по всем пунктам вашего списка), но так как оно никогда не было мое - мне остается только считать его странным, не более того. И да, мне такие таблицы встречаются хорошо если одна на 10000 обычных, а у меня чужих СУБД для интеграции сотни.


  1. DikSoft
    01.07.2024 18:37
    +2

    Редко в наше время статья попадает в раздел "здравый смысл". Эта точно попала. Спасибо автору!


  1. Gmugra
    01.07.2024 18:37
    +7

    Микросервисы это по определению - архитектурный паттерн распределенного приложения.

    И да, что часто забывают это то, что "распределенное приложение" это всегда сложно.
    Независимо от того микросервисы это или какие-нить CORBА/RPC/SOAP или еще что там у нас в прошлом было модно.

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

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

    p.s. Собственно даже евангелисты типа Фаулера давно говорят что начинать прям с микросервисов не надо: Monolith First типа...


  1. emerald_isle
    01.07.2024 18:37

    Да, прямо сегодня трогаю монолит (возрастом более пятнадцати лет наверное по грубым оценкам), и таки да, он ужасен.


    1. xxxDef
      01.07.2024 18:37
      +2

      Яркая иллюстрация того как слово "говнокод" зачем то заменяют на "монолит"


      1. emerald_isle
        01.07.2024 18:37

        Там всё несколько сложнее. Но объяснять по-нормальному долго, скучно, и наверняка нарушит NDA.

        Таки с кодом там тоже проблемы, но это не главное, они менее критичны. Я про архитектуру.

        Волшебной таблетки не существует, просто взять и сделать как надо за пару дней всё равно невозможно. Дешевле (и менее рискованно) аккуратно трогать этот монолит палочкой. =) И аккуратно распиливать частями.


  1. titan_pc
    01.07.2024 18:37

    Классная статья. Покуда команда работает на одном языке модули/библиотеки+моно-репка рвут микросервисы. Просто потому что необходимость коммуникации между ними по сети отпадает. Однажды кто-то это окрестил термином "Квантовый-сервис" (Моно-репа, в которой все технологические вещи выпилены в свои собственные бибилотеки/компоненты, то есть что мы делаем отделено от того как мы это делаем. А сверху это всё рождает столько единиц деплоя, сколько хочется, обычно разделение по DDD или как то ещё чтобы на уровне API были чёткие границы ответственности). Но термин так и не прижился.


  1. Nashev
    01.07.2024 18:37
    +2

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

    Дык а в итоге, какой ответ был бы красивым и правильным? Растекание мыслью по древу, что "it depends, разбираться в задачах надо...῞?


    1. Captain_Jack Автор
      01.07.2024 18:37
      +1

      Да, справедливо замечено.

      Для меня красивый и правильный ответ - это иметь собственное понимание, а не слепо повторять какие-то услышанные фразы.

      То есть, даже если я сейчас напишу красивый ответ и вы его повторите мне на собесе, я всё равно буду недоволен, хотя возможно чуть меньше - когда человек повторяет не супер-странные тезисы, а что-то имеющее отношение к действительности, то это уже чуть лучше, хоть и не сильно. Как я это проверяю? Всё просто: я спрашиваю вопросы "а почему так?", "а когда эта штука может пригодиться?", "а когда так делать не надо?". Потому что это как раз важно, когда принимаешь решения в работе. И нагуглить такое в моменте обычно непросто, когда это нужно. Нужно заранее потратить время, чтобы разобраться в инструменте.

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

      Но что я хожу вокруг да около, на такой вопрос я бы ответил коротко так:

      Микросервисы - это такой архитектурный стиль, в котором мы разбиваем нашу доменную и техническую логику на довольно мелкие модули, каждый модуль имеет свою осмысленную ответственность и выносится в отдельный сервис. Сервисы инкапсулируют свою внутреннюю реализацию и общаются через выставленный API. По классике это JSON over HTTP, но сейчас это целое поле разных вариантов, синхронных и асинхронных. При этом каждый микросервис является самодостаточным - он разрабатывается, релизится и эксплуатируется как отдельная независимая единица. Микросервисные системы являются распределёнными, и каждый микросервис реализован с пониманием, что его зависимости могут быть периодически недоступны, а данные могут быть неконсистентны.

      Нафига оно надо? Главная причина для многих компаний - чтобы эффективно строить разработку с большим количеством команд, при этом имея хорошую скорость поставки изменений. Если у вас 2-3 команды, вам это будет не так инетерсно, если 10 - то уже очень вероятно.

      И в целом возможность эксплуатировать микросервисы независимо друг от друга даёт много профита в прозрачности эксплуатации - можно предъявить к сервисам разные требования по SLA, защите персональных данных, отдельно бэкапить данные, тестить нагрузку, собирать логи, обвешивать мониторингом и алертингом.

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

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

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

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


  1. ShashkovS
    01.07.2024 18:37

    Лет 8 работал с IBM iSeries (AS400, System I). И был там у нас монолит.
    Но, ИМХО, монолит частично «здорового» человека: там ось обмазана фиксированным ABI, поэтому из программы на одном любом языке ты непосредственно без плясок вызываешь программу на другом (если нужно).
    Разные модули — наборы текстовых файликов, которые компилируется независимо друг от друга. Что-то где-то поменял, и если внешний API не меняется, то просто перекомпилируешь — и всё.
    А чтобы типы не ползли, есть конструкция like — сделай переменную того же типа, что и другая.

    Вот этой мега-компиляции проектов на java, C++, rust там просто нет. Но правда другие, свои, проблемы и сложности есть :)


  1. sinka463
    01.07.2024 18:37

    наверное можно добавить еще парочку измерений до полного хаоса: облака и кубернетес


  1. sshikov
    01.07.2024 18:37

    Вы знаете, ужасные монолиты таки наверное существовали. Скажем, возьмем то, что называлось J2EE. Вот где-то до версии 3 создание модулей в этом фреймворке было сделано ужасно неудобно. Но даже в этом случае модули все равно всегда были, их можно было по отдельности деплоить, обновляя часть функциональности, запускать и останавливать.

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


  1. ryanl
    01.07.2024 18:37

    Ну холивар о том что лучше - монолиты или микросервисы - и правда давно прошел. Однако эти три пункта о чем думает индустрия сейчас - модули/репы/артефакты - полный баян. Индустрия всегда думала о таких вещах, это просто дизайн и архитектура проектов и физическая/логическая организация кода. Все это всегда имело место с тех пор, как зародилась разработка ПО как индустрия.


  1. Akakist
    01.07.2024 18:37

    Берите мегатрон, там все, о чем вы говорите, уже есть. Быстрее нгинкса на пару процентов, быстрее усервера в 17 раз. Eсть даже телнет, парой строчек можете организовать консоль управления процессом.
    https://github.com/akakist/megatron


  1. KV-excavator
    01.07.2024 18:37

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


  1. LeoKudrik
    01.07.2024 18:37
    +1

    Я бы добавил ещё одно измерение на месте автора - вопрос изоляции (корутина, поток, процесс, контейнер, ...). Но тогда статья была бы гораздо больше :)


  1. Alextptr
    01.07.2024 18:37

    Заканчиваю курсы по Веб-программированию, пишу итоговую работу. Читал статью как-будто на китайском, вообще ничего не понял. Нас чему-то не тому учат?


    1. Captain_Jack Автор
      01.07.2024 18:37
      +1

      Просто не всё сразу, я только лет 5 поработав стал этими темами интересоваться. Ни в какие курсы и вузы не впихнуть те знания, до которых доходишь, набираясь опыта и экспертизы.


    1. Cerberuser
      01.07.2024 18:37
      +2

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


    1. Nashev
      01.07.2024 18:37

      У вас там микро-фронтенды должны были упомянуть )))


  1. nlog
    01.07.2024 18:37
    +1

    Еще есть зависимость от размера организации, точнее штата инженеров. Если у нас, допустим, 1000 инженеров, то им будет проще работать с микросервисной архитектурой, когда по одному нажатию кнопки ты можешь создать новый репозиторий, БД, конфиги деплоя на dev и prod, чтобы быстро начать писать код, деплоить и тестировать гипотезы уже сегодня, а не завтра, когда пайплайны в монорепе аккуратно поправят, чтобы не было

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


  1. Yuriy_75
    01.07.2024 18:37
    +1

    С посылом согласен. Только хочу заметить, то что у разработчиков каша в голове - это еще половина беды. Настоящая беда - это каша в голове у архитекторов и IT руководителей. Которые и принимают ничем не мотивированные решения "пилить монолит", потому что это модно.


  1. vanya6194
    01.07.2024 18:37
    +1

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