Как стать автором
Обновить

Макропроблема микросервисов

Время на прочтение 10 мин
Количество просмотров 16K
Всего голосов 29: ↑24 и ↓5 +19
Комментарии 17

Комментарии 17

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

Есть поддежка Golang и скоро появится PHP.

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

А почему ведет «недоиспользованию ресурсов» и «перестает работать»?

Вот есть, условно, очень большое приложение. Что мешает поднять 100500 его инстансов? Да, вероятно придется разным его инстансам завести разные типы запросов — чтобы разные подсистемы в нем включались, и разумнее использовалась бы память. Если используется RDBMS — придется продумать как в него не упереться (шардинг, разбить на разные БД, read-реплики, кеши), но это и с микросервисами оно так.

Какие будут там проблемы, что этот подход перестанет работать?
Когда хайп прошел, а он прошел, примерно так и пишут множество софта.
Монолит подготовили для горизонтального маштабирования и научили расти линейно от нагрузки. С такой архитектурой живется отлично.
И самое главное никаких распреденных транзакций. Все лежит вот в этой БД и меняется атомарно под обычной локальной транзакцией.
Все падения обрабатываются обычным http балансером. Один ретрай на балансере дает и возможность упасть и даст не более х2 нагрузки в самом невероятно плохом случае.

Просто и надежно.

Против микросервисов.


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


В то время как в Монолите мы вызываем функции напрямую, и переходим между ними одним кликом мышки в IDE, в микросервисах передаются недокументированные куски JSON через недокументированное API. Ищи, разбирайся, что тут пошло не так.


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


Отдельная проблема — общий код. Что, если сервису A и B нужно использовать общий код? Приходится либо копипастить (и вносить изменения в несколько копий кода), либо выносить в библиотеки и мучаться с версионированием и оркестрацией кучи микросервисов и бибилиотек. В то время как в Монолите этой проблемы просто нет изначально.


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


Монолит может все то же, что и микросервисы, только лучше и без Докера. Хочется масштабирования — запускаем несколько копий Монолита на нескольких серверах. Нужна очередь? Делаем очередь и запускаем две копии Монолита — писатель и читатель. Уперлись в производительность сервера БД? — переделываем Монолит на работу с несколькими разными серверами БД. Получается то же масштабирование как в микросервисах, но без боли, разных языков и без докеров.


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


Некоторые жалуются на запутанный код в Монолите. Это не аргумент. Если разработчики не способны написать чистый код в Монолите, они и микросервисы такие же нечитаемые напишут. Некоторые думают, что микросервисы будут "маленькие" и "простые". Это не так. Если подумать логически, то суммарный объем кода в микросервисах = объем кода в Монолите + накладные расходы на передачу данных. То есть в сумме микросервисы по объему будут больше Монолита.

Зато микросервисная архитектура идеально ложится на закон Мёрфи Конвея.

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

> где надо и (очень часто) где не надо.
скорее даже так — очень редко где надо и почти всегда где не надо

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

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

Хотя я вижу, что это происходит с каждой модной технологией.

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

в микросервисах передаются недокументированные куски JSON через недокументированное API

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

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

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

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

так а что, в монолите разбираться не надо, если не знаком с кодовой базой? вообще странный аргумент, потому что если ты участвовал в разработке проекта, то много чего «изучать» не надо будет, а если не участвовал — так и так разбираться (и чем больше проект — тем дольше разбираться, независимо от его структуры).

Простая задача, в монолите решаемая за несколько часов, займет несколько дней, а то и недель

какие-то цифры с потолка, непонятно откуда взятые

Отдельная проблема — общий код. Что, если сервису A и B нужно использовать общий код?

монорепозиторий

Таким образом, с помощью Монолита можно добиться той же производительности и масштабируемости, только без головной боли и присущих микросервисам недостатков

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

Хочется масштабирования — запускаем несколько копий Монолита на нескольких серверах

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

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

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

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

Что произойдёт, если во время выполнения Workflow.sleep(Duration.ofDays(30)); изменить последующий шаг и передеплоить? А если добавить внешний блок? Или вовсе убрать тот шаг, на котором в данный момент происходит ожидание?

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

Кто-нибудь может объяснить чем микросервисы отличаются от SOA (сервис ориентированная архитектура)?

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

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

Зарегистрируйтесь на Хабре , чтобы оставить комментарий