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

Полностью согласен с тезисами из упомянутой статьи про то что 90% типичных аргументов про преимущества микросервисов не имеют никакого отношения к микросервисам:

  • Возможность писать на разных языках — уже лет 50 сотни монолитов пишут на разных языках.

  • Говнокод в микросервисе не перестанет быть говнокодом.

  • Стейтлес монолиты масштабируются так же хорошо как и микросервисы

и так далее.

Так же полностью соглашусь что микросервисы привносят достаточное количество стандартных сложностей:

  • Распределенное изменение данных зачастую без ACID гарантий

  • Более сложная отладка

  • Проседание перфоманса

и так далее

Но у микросервисов есть одно ключевое преимущество — deploy fast за счет уменьшения единицы деплоймента. Давайте разбираться.

Возьмем классический монолит, которому уже лет 20. Допустим он написан на дотнете и это один солюшн с сотней проектов, которые на выходе собирается в один большой контейнер(докер 5 лет назад прикрутили). Над этим солюшном работают 5–7 команд, у каждой из которых есть манагер, беклог и бизнес заказчик. Все это лежит в одной репе и используется какая то разновидность фичер бранчинга: каждая юзер сторя делается в отдельном бранче которая мержится в девелоп, в котором тагятся релизы.

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

Теперь давайте просмотрим на это глазами бизнеса. Бизнес обычно хочет чтобы его запросы были сделаны вчера. А тут получается что реализацию минимального запроса надо ждать полгода. Естественно это вызывает недовольство.

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

И вот приходят микросервисы. Минимальная единица деплоймента. Микросервис разрабатывает одна команда. Никаких согласований для выкатки. Регресионное тестирование делается за полдня. И как следствие — релиз каждые 2 недели. Бизнес видит результат вот уже сразу.

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

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

Из чего следует, что стабильность контрактов — основа успеха проекта с микросервисами. А стабильность контракта достигается правильным разбиением бизнес домена на микросервисы. Правильное разбиение бизнес домена на микросервисы достигается опытом работы в бизнес домене.

Как то так, итоги подведем.

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

И да, микросервисы — это про процесс и deploy fast, и только во вторую очередь про технологии.

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


  1. ErshoffPeter
    10.07.2024 05:23
    +4

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

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


    1. ktarasov
      10.07.2024 05:23
      +1

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


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      Хорошие монолиты я видел и даже сам писал, но ни разу не встречал QA, который смотрит на ченджи единицы деплоймента, и верит на слово программисту что «там ничего не поломалось, регрессия не нужна».


      1. ErshoffPeter
        10.07.2024 05:23

        Тестирования бывает либо мало либо совсем мало.

        Если QA видит, насколько локализованы изменения - то он и включает в тест-кейсы.


        1. sergey_prokofiev Автор
          10.07.2024 05:23

          Тестирования бывает либо мало либо совсем мало.

          … на вашем проекте.


          1. ErshoffPeter
            10.07.2024 05:23

            А на вашем проекте?

            ...вам удаётся тестированием охватить каждый раз все возможные последствия изменений?


            1. sergey_prokofiev Автор
              10.07.2024 05:23

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


  1. hren-s-gori
    10.07.2024 05:23
    +2

    Но у микросервисов есть одно ключевое преимущество — deploy fast за счет уменьшения единицы деплоймента.

    То же так себе аргумент. У "монолитов" это тоже всегда было предусмотрено: dll/assembly/package.


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      вполне ввриант, главное развести релиз циклы. На практике не встречался. Но это тежи микросеовисы, но на одном железе :)


      1. hren-s-gori
        10.07.2024 05:23
        +1

        Но это тежи микросеовисы, но на одном железе :)

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


        1. sergey_prokofiev Автор
          10.07.2024 05:23
          +1

          если мне на практике не приходилось с таким велосипедом сталкиваться, то это не значит что я не знал что так можно:)

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


          1. hren-s-gori
            10.07.2024 05:23
            +1

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


            1. sergey_prokofiev Автор
              10.07.2024 05:23

              Радость для пользователей - это геморрой для разработчика. В микросервисах «радости» больше, в монолитах - меньше и иногда вообще нет. В вашем примере деплоя отдельными либами все тежи проблемы и с микросервисами. Вы точно прочитали прежде стали каментить?


              1. hren-s-gori
                10.07.2024 05:23

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


                1. sergey_prokofiev Автор
                  10.07.2024 05:23
                  +1

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

                  Значит у нас приблизительно одинаковый опыт и наверное мы +- ровесники.

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

                  Статическая линковка в большом количестве кейсов позволяет сделать это одним тыком мыши в «refactor this”. И это безусловный вин статической линковки и монолитов. Банально потому что чисто количественно, надо гораздо меньше кейсов покрывать.


                  1. hren-s-gori
                    10.07.2024 05:23

                    Статическая линковка в большом количестве кейсов позволяет сделать это одним тыком мыши в «refactor this”.

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


                    1. sergey_prokofiev Автор
                      10.07.2024 05:23

                      Ну обычно такие реквесты приходят от бизнеса и тут сложно аргументировать что "вы не понимаете что вам надо на самом деле". И дальше вопрос в цене вопроса на изменение - ок, если "refactor this" не получится, то оно не соберется и надо будет в режиме "жопа в мыле" фиксить, иначе не получится выкатить. Соотвественно проблема версионности минимизируется и все проблемы решаются до выкатки релиза - соотвественно это проще/дешевле чем сапортить несколько версий. Но случаи бывают разные и there is no a silver bullet


                      1. hren-s-gori
                        10.07.2024 05:23
                        +2

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


                      1. sergey_prokofiev Автор
                        10.07.2024 05:23

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


  1. SpiderEkb
    10.07.2024 05:23
    +3

    Возьмем классический монолит, которому уже лет 20. Допустим он написан на дотнете и это один солюшн с сотней проектов, которые на выходе собирается в один большой контейнер(докер 5 лет назад прикрутили). Над этим солюшном работают 5–7 команд, у каждой из которых есть манагер, беклог и бизнес заказчик. Все это лежит в одной репе и используется какая то разновидность фичер бранчинга: каждая юзер сторя делается в отдельном бранче которая мержится в девелоп, в котором тагятся релизы.

    Такое ощущение, что "против монолитов" специально придумываются примеры пострашнее.

    В реальности же скорее все происходит как описал коллега @ErshoffPeter

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

    Мы тоже работаем с АБС

    производители основных АБС сейчас так релизятся

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

    Как пример. Есть команда системы расчетов (СР). В числе прочего у них есть сервис контроля платежей. И в нем есть проверки платежа по линии комплаенса. Которые уже делаем мы - команда автоматизации процессов комплаенс-контроля.

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

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

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

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

    Аналогично журнальные мониторы. Есть движок который отследивает изменения в таблицах по системным журналам и вызывает соотв. мониторы по имени таблицы (опять по настройкам). Каждый монитор разрабатывается, отлаживается и деплоится отдельно. В деплой входит бинарник самого монитора + накат настроек в конфигурационные таблицы.

    И все это никак не микросервисы. Но и монолитом, как таковым, не назовешь.


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      Такое ощущение, что "против монолитов" специально придумываются примеры пострашнее.

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

      Которые уже делаем мы - команда автоматизации процессов комплаенс-контроля.

      сколько девов в команде, как часто вы релизитесь и какой обьем регрессии ранят QA?


      1. SpiderEkb
        10.07.2024 05:23
        +3

        сколько девов в команде

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

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

        Был ретривер - задаешь клиента, получаешь текущую ДА.

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

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

        Ну и ретривер переписали - теперь он не ищет по основной таблице, а просто берет запись по уникальному ключу из витрины.

        Вкатили два модифицированных модуля (update + retrieve), запустили скрипт первоначального заполнения витрины и вуаля - всем кто пользуется этим параметром сразу стало лучше.

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

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

        "Коллеги, сервис *** за последние 5 недель увеличил потребление процессорных ресурсов в 3 раза!!!
        Он уже является 2-м по величине сервисом после *****. В качестве альтернативы мы рассматриваем перенос запуска сервиса на резервный сервер, но там есть лаг по отставанию до 10 мин.
        Заказчикам сервиса это может не понравиться :("

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

        "Коллеги, доброе утро!
        Спасибо!
        Уже утром видим очень хороший результат!!!
        Доработка сокращает потребление процессорных ресурсов почти в 10 раз!"

        Иногда (если речь шла о каких-то ну очень критических вещах), после этого еще следует что-то типа такого:

        Коллеги, добрый день

        Вам сегодня должна прийти премия за особый вклад в развитие и оптимизацию нашей АБС, который сделан в рамках проекта *****, в части оптимизации процедур ****** в части комплаенс процедур и проверок (сокращение c 2 часов до 40 минут), ускорении процедуры *****, оптимизацию проверки ******

        Ценим ваши усилия в этом и других направлениях вашей работы, неравнодушное отношение и подход!
        Спасибо!

        Это сверх регулярных бонусов, естественно.

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

        И у нас всегда одна задача - одна поставка - один разработчик.

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

        как часто вы релизитесь

        Если говорить в целом по серверу, то 5-10 поставок ежедневно. Причем, поставка может содержать как 1-2, так и 10-15 объектов. У меня как-то была поставка из 180-ти объектов... Но это скорее исключение.

        какой обьем регрессии ранят QA

        Каждая поставка обязательно проходит полный цикл тестирования. Сначала первичное - в песочнице. Потом компонентное (в компонентных юнитах) - на соответствие FSD. Дальше идет бизнес-тест (на соответствие BRD) это уже другой юнит. Далее - интеграционное. Потом нагрузочное тестирование на копии промсреды. Заключительный этап - техтест на прелайв юните. И только после этого внедрение.

        Любое изменение кода тащит за собой полный цикл тестирования. Это банк. АБС. Центральные сервера. Цена ошибки может исчисляться суммами с очень многими нулями.


        1. sergey_prokofiev Автор
          10.07.2024 05:23

          сотни полторы-две разработчиков.

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

          Каждая поставка обязательно проходит полный цикл тестирования. 

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

          Если говорить в целом по серверу, то 5-10 поставок ежедневно.

          не совсем правда


          1. SpiderEkb
            10.07.2024 05:23

            Либо у вас все очень хорошо с автоматизацией,

            О какой автоматизации речь?

            не совсем правда

            Я сужу по ежедневной рассылке "Что делаем" от сопровождения. Там, в том числе, список поставок которые сегодня внедряются на пром.

            Бэклог у каждого разраба достаточно длинный. И обычно ведешь сразу 2-3 задачи. Одна уходит в тест, сразу делаешь вторую, третью. И тут длина "конвейера" никак не влияет на его производительность. То, что внедряется сегодня, разрабатывалось не вчера и не позавчера даже. А что будет внедряться завтра не сегодня делалось.


            1. sergey_prokofiev Автор
              10.07.2024 05:23

              О какой автоматизации речь?

              о стандартной автоматизации, которая меряется % покрытия юзкейсов

              Я сужу по ежедневной рассылке "Что делаем" 

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


              1. SpiderEkb
                10.07.2024 05:23

                Ну я уже описал наши процессы.

                Кратко - есть некая система. Очень большая. Примерная оценка (не самая свежая) такова

                • 27 тыс. программных объектов

                • 15 тыс. таблиц и индексов базы данных

                • Более 150 программных комплексов

                • Занимает более 30 Терабайт дискового пространства

                • В день изменяется более 1,5 Терабайт информации в БД

                • За день выполняется более 100 млн. бизнес операций

                • Одновременно обслуживается более 10 тыс. процессов

                • За год происходит более 1100 изменений в алгоритмах программ

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

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


                1. sergey_prokofiev Автор
                  10.07.2024 05:23

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

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


                  1. SpiderEkb
                    10.07.2024 05:23

                    Мне не совсем понятна причина, по которой может потребоваться изменение контракта.

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

                    В этом случае старую функцию не надо трогать а делать новую.

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

                    Так что с контрактами проблем у нас нет.


                  1. hren-s-gori
                    10.07.2024 05:23

                    , но геморрой с версионированием.

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


                    1. sergey_prokofiev Автор
                      10.07.2024 05:23

                      Нет никакого геморроя и с версифицированием. 

                      Другие команды потихоньку переезжают на новые версии вашего компонента, можно спокойно дропать старые контракты

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


                      1. hren-s-gori
                        10.07.2024 05:23

                        Да, эти проекты - публичные проекты с миллионами пользователей. Вот там геморрой тащить обратную совместимость 10-20 летней давности.


                      1. sergey_prokofiev Автор
                        10.07.2024 05:23

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


  1. maxzh83
    10.07.2024 05:23
    +1

    • Стейтлес монолиты масштабируются так же хорошо как и микросервисы

    Не совсем также. Микросервисы можно масштабировать точечно, монолит только целиком. Грубо говоря, у вас в монолите 500 ендпоинтов, из них 50 высоконагруженные, остальные - нет. Масштабировать придется целиком весь монолит. В случае с микросервисами масштабируете только нагруженные сервисы.


    1. amphasis
      10.07.2024 05:23
      +2

      Масштабировать придется целиком весь монолит

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


      1. maxzh83
        10.07.2024 05:23

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


        1. amphasis
          10.07.2024 05:23

          настраивать балансировщик

          Да, какие эндпоинты будут обрабатываться выделенными инстансами настраивается в том же nginx, например.

          какие-то ресурсы все равно отжираются большим монолитом

          Так микросервисы тоже не бесплатные :)


        1. dph
          10.07.2024 05:23

          В тот же Spring еще лет 15 назад можно было поднять монолит с подключенными только частично модулями.
          Балансировка по конкретным сервисам - обычный APIGW или меш, тут нет проблем особых.


          1. maxzh83
            10.07.2024 05:23

            Понятно что можно, просто не видел, чтобы так делали


    1. patex
      10.07.2024 05:23
      +3

      плохой пример, ненагруженные ендпоинты в монолите после масштатбирования много ресурсов не съедят.


      1. maxzh83
        10.07.2024 05:23

        В целом да, но есть еще оперативная память, диск и всякие фоновые активности, которые часто встречаются в монолитах.


        1. sergey_prokofiev Автор
          10.07.2024 05:23

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


    1. Xexa
      10.07.2024 05:23

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

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

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

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

      А как мило на старой версии клиента проводить исправления ошибок или доработку...

      Замечательная тема с микросервисами. Если они независимы. Но это уже какая-то "сыерическая система в вакууме".


      1. sergey_prokofiev Автор
        10.07.2024 05:23

        дык вот в том то и сложность, что иногда нужны микросервисы, иногда монолиты. Про проблему версионности микросервисов вроде ж расписал подробно - да, api/v1, api/v2 всегда гемор, но что делать


    1. dph
      10.07.2024 05:23

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


  1. dabel1k0v
    10.07.2024 05:23

    А вы всё мой перевод репостите. Плагиатчики чёртовы.


    1. Vedomir
      10.07.2024 05:23

      Почитал перевод по ссылке, почитал оригинал, поставил в очередь почитать ссылки с оригинала, оба классные, но где здесь репост?


      1. dabel1k0v
        10.07.2024 05:23

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


        1. sergey_prokofiev Автор
          10.07.2024 05:23
          +1

          Зачем вы здесь это пишете? Я сослался на статью опубликованную на хабре. Если у вас вопросы про авторство статьи, на которую я сослался - пишите в каментах к той статье, или напрямую модераторам. Тут зачем?


    1. Captain_Jack
      10.07.2024 05:23

      Всё-таки некрасиво обвинять людей в плагиате ради подгона траффика на свой материал.

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

      Не надо так.


      1. dabel1k0v
        10.07.2024 05:23


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      ваш перевод не читал. Обвинение голословное.


    1. Vedomir
      10.07.2024 05:23

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


  1. dph
    10.07.2024 05:23

    Я вот вспоминаю свои монолиты.
    Ну, где весь код был внутри СУБД, там было грустно, сборка релиза и раскатка занимала где-то сутки (с учетом поездки к клиенту с дискеткой, это была B2B коробочка). Релизы делали раз в неделю-две, причем можно было привозить к клиенту только новые версии отдельных модулей.
    Где-то код был уже на Java, там сборка с автотестами занимала час-два (и да, транк был всегда с прошедшими автотестами, а модульные тесты делались локально и до коммита), развертывание на 12 серверов на 3 датацентра занимало секунд 10.

    Я не понимаю, какие МСА будут быстрее и, главное, зачем быстрее...


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      ну если релиз цикл 2 недели, то наверное микросервисы не нужны.

      В моей практике был монолит, релиз цикл которого занял 3+ года и работало больше 100 девов постоянно. На пиках за 150. ПМ, QA и тд сверху. Бизнес мягко говоря был не очень доволен


      1. dph
        10.07.2024 05:23
        +1

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


        1. sergey_prokofiev Автор
          10.07.2024 05:23

          дык в том то и дело, что поможет. Понятное дело что это root cause не порешает, но даст эффект.

          А какие варианты у типичного энтерпрайза? Уволить 200 человек, вместо них нанять новых, которые пару лет будут вьезжать в бмзнес домен и код 20 летней давности и только потом возможно(если наняли профи) начнут что-то деливерить?


          1. dph
            10.07.2024 05:23

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


            1. sergey_prokofiev Автор
              10.07.2024 05:23

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

              И да, микросервисы — это про процесс и deploy fast, и только во вторую очередь про технологии.


      1. SpiderEkb
        10.07.2024 05:23
        +1

        Не очень понятно что такое "релиз-цикл" в вашем понимании.

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

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

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

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

        И вот что тут считать релиз-циклом? Время TTM для одной поставки? Оно достаточно велико в силу жестких требований по тестированию (которое обычно занимает больше времени по сравнению с разработкой).

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

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

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

        Вот как-то так все это работает.


  1. bak
    10.07.2024 05:23
    +1

    Если есть автотесты - релизить можно хоть по 10 раз в день, что монолит что микросервисы.


    1. sergey_prokofiev Автор
      10.07.2024 05:23

      и да и нет:)

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

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


      1. dph
        10.07.2024 05:23
        +1

        А почему автотесты пишет другая команда? Это часть DoD для фичи и пишется той же командой.


        1. sergey_prokofiev Автор
          10.07.2024 05:23

          потому что:)

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

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


          1. bak
            10.07.2024 05:23

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


            1. sergey_prokofiev Автор
              10.07.2024 05:23

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


              1. bak
                10.07.2024 05:23

                Для таких компаний критичность автотестов ещё выше.

                Хотя есть очень странные компании которые не пишут автотесты и тестируют всё руками. Наблюдал за таким лично. Как итог - регулярные регрессии с озвученной вами ценой ошибки. Но там месячная прибыль с 6-7 нулями - могут себе позволить.


                1. sergey_prokofiev Автор
                  10.07.2024 05:23

                  отож