Хватит везде делать микросервисы

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


    image


    Микросервисы — это плохо, и вот почему


    Микросервисы затрудняют разработку


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


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


    Микросервисы требовательны к инфраструктуре


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


    Микросервисы затрудняют развёртывание


    Вот представьте себе, вам нужно выкатить на продакшен какую-то новую фичу. Окей, вы готовите репозиторий, собираете контейнеры (у вас ведь Docker, правда?). И наступает время деплоя. И тут, вам придётся аккуратно последовательно отключать все ваши микросервисы и накатывать новые версии. Процесс долгий, многое может пойти не так. Монолит — если запустился, уже хорошо. А с микросервисами — что-то запустилось, что-то нет — и придётся откатывать всё к предыдущей версии. А если уже миграции базы применились — то вообще пиши пропало.


    А когда микросервисы — это хорошо?


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


    Когда нам нужно масштабировать сервисы по-разному


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


    Когда сервис должен выжить, при падении какой-то функциональности


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


    Когда у вас в компании уже давно сложившийся зоопарк технологий


    Когда половина бекендеров пишут на Python, половина на PHP, а ещё 46% на Perl, то без микросервисов тут не обойтись. Языки, особенно, скриптовые, слабо умеют интегрироваться между собой.


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


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


    А ещё этот пост доступен в формате видео на моём YouTube-канале.


    Видеоверсия

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

      –17
      да не делай, нам больше достанется
        +1
        И наступает время деплоя. И тут, вам придётся аккуратно последовательно отключать все ваши микросервисы и накатывать новые версии.

        Вы все еще катите руками?

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

        На единственном сервере

        Ну тогда полностью согласен — Вам не нужны микросервисы.
          +1

          Да, именно. У автора похоже "расспределенный монолит", деплой в продакшен раз в месяц и недопонятые преимущества микросервисов.

          +6

          Очередной пост в котором противостояние "монолит против микросервисов". А надо — "сервисы против микросервисов". Но слово "сервис" слишком простое для buzzword, так что надо всегда говорить "hyper-convergent micro service".

            0

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

              +2

              Ровно так же можно утверждать, что монолитное приложение со встроенной базой данных и веб-сервером — это вариант микросервиса с кардиналити 1. Формально — да, фактически, извращение идеи.


              Микросервисы от сервисов различаются подходом к архитектуре взаимодействий. На сервисы выносятся куски исходя из внешней логичности (data locality, proximity) или целей резервирования, на микросервисы выносятся куски кода исходя из финансовой мотивации сдать на программирование джуниорам/аутсорсу и изоляции от криворукости оных за счёт сетевого контракта.

            +3
            проверяем идею — взлетела или нет. А уже потом думаем, переписывать на микросервисы или нет.

            Ага, вот только это «потом» никогда не наступает — бизнесу нет времени менять архитектуру приложения, бизнесу есть время добавлять новые фичи. В итоге монолит обрастает функционалом, костылями и со временем превращается в макароны. Зависимости сложности поддержки от размера кода квадратичная.
              +4

              "Потом" наступит, но со временем, только когда это будет оправдано экономически.
              Тут нужно искать баланс между стоимостью разработки и поддержки. Если стоимость поддержки становится высокой, то руководитель разработки или тимлид сможет прийти к бизнесу и получить для команды время на рефакторинг. Главное — перевести сложность поддержки в понятные бизнесу метрики: Time-To-Market, например.

                +1
                только когда это будет оправдано экономически.

                «Пока ты тут будешь свой код рефакторить — конкуренты выкатывают новые фичи».
                «Зачем тебе рефакторить? Ты плохой программист и написал говнокод?»

                Да у бизнеса бывает сотня отмазок почему время рефакторинга — это впустую потраченное экономически время. TtM считается в попугаях, нельзя сказать что еще месяц и всё. Нет точных метрик — нет санкций.
                  +6
                  Когда пилят новый модный стартап, ещё не понятно из каких подсервисов надо делать готовый продукт, но любители микросервисов, которые не могут отказаться от этой идеи начинают дробить продукт на микросервисы попросту на угад. При этом спорят по пол дня сколько тут надо микросервисов сделать 4 или 6.
                  В результате такого искусственно деления получается реальный говногод. Обычно в этот момент «команда удачи» успешно увольняется.

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

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

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

                    Разбитие монолита на отдельные куски(или уже тем более микросервисы) это не то чтобы тривиальная задача. И даже не то чтобы обязательно решаемая. Ну в том плане что часто будет дешвеле/быстрее просто взять и написать всё заново.
                0
                В итоге монолит обрастает функционалом, костылями и со временем превращается в макароны.

                А микросервисы каким-то магическим образом защищены от костылей и плохого кода?

                Я бы сказал, что даже наоборот — общий объем кода с микросервисами вырастает, общий объем работы вырастает, и если разработка проходит в сжатых сроках — то результат будет еще печальнее, чем на монолите.

                Впрочем, разработка с горящими сроками никогда ни к чему хорошему не приводит.
                +2
                сейчас тренд уже не микросервисы — а лямбды.
                  +1
                  Стоит разделять понятие «монолита» и приложения на единой кодовой базе

                  «Монолит» является анти-паттерном: синонимом "легаси", плохо спроектированного, сильно и неявно связанного, не тестируемого приложения

                  Single-repo приложение может быть хорошо спроектированным, тестируемым, модульным, слабо связанным, легко расширяемым
                    0
                    Хорошо сказано.
                      0
                      Что такое «приложение на единой кодовой базе»?
                      Составные такого приложения могут стартовать самостоятельно или имеется ввиду что-то типа DDD с одной точкой входа/старта?
                        0
                        Если говорить о бэкенде/десктопе:
                        одно приложение на один бизнес-проект; в одном репозитории; написанное на одном языке программирования.

                        Точек входа может быть много, как и окружений, как и собранных бинарников
                        +1
                        «Монолит» — никак не связан с плохо, неявно или чем-то еще. Это просто тип архитектуры приложения. Все. Превратится ли монолит в плохое, неявно связанное и нетестируемое легаси зависит от того какие решения будут приниматься в процессе развития и насколько профессиональны были разработчики что это писали.
                          0
                          Из википедии "Monolithic system":
                          A software system is called «monolithic» if it has a monolithic architecture, in which functionally distinguishable aspects (for example data input and output, data processing, error handling, and the user interface) are all interwoven, rather than containing architecturally separate components.

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

                          Я считаю, что это определённо плохо. Это как «бизнес-логика в шаблонах отображения». Отсутствие структуры, архитектурных слоёв, инверсии зависимостей и проч.
                            0

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

                              +1
                              Если таскать через CI/CD аналогичные по суммарному объёму кусочки монстра — процессорного времени сборщиков будет израсходовано сильно больше, если учитывать все дополнительные расходы на сбор контейнеров, pre/post действия. И суммарный объём — это в идеальном случае; в реальности микросервисы часто дублируют функционал друг друга, так что кода в них оказывается больше, чем в single-repo приложении, даже если они идентично повторяют бизнес-логику последнего
                        +11
                        Я не параноик, но иногда мне кажется что концепция микросервисов и модных нынче лямбд – заговор облачных провайдеров, чтобы стричь больше бабла с квадратично возрастающих затрат на инфраструктуру.

                        Такое ощущение, что все вменяемые архитекторы вымерли, а им на смену пришли вчерашние джуны, которые не могут в голове удержать больше чем 3 ендпоинта и 2 аргумента.

                        Я уж не говорю о том, что обеспечение reliability всего этого зоопарка требует целого нового квалифицированного отдела внутри компании.
                          +2
                          > А когда микросервисы — это хорошо? — Когда у вас несколько команд, которые независимо делают разные компоненты сервиса.

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

                            Тут основные плюсы с точки зрения процессов это независимый деплой (проще тестировать и выкатывать/откатывать по кусочкам) и гарантия того, что другие команды не сунутся туда, куда им соваться не нужно, и не будет конфликтов при мержах (изоляция), также форсируется общение через чётко документированное API (нельзя взять и накостылять что-то в обход). Когда над монолитом работают несколько команд, постоянно что-то отваливается/не собирается, нужно разруливать какие-то конфликты при мержах, другая команда залезла в твой код и накуролесила, поменяли общий класс-зависимость и поведение немного поменялось, но сломало твои кейсы и т.д. (это даже при DDD). С микросервисами вообще в этом плане лепота - присутствует какая-то стабильность, при переходе от задачи к задаче и мержах старых задач есть уверенность, что оно с вероятностью 99.99÷ заведется без проблем и будет работать так же, как в прошлый раз оставил

                              0

                              >Библиотеки никто не отменял.

                              Не во всяком монолите можно использовать разные версии общих библиотек одновременно. Если команда 1 обновила общую зависимость, то код команды 2 может сломаться. С микросервисами можно применить версионирование, т.е. один микросервис использует одну версию, другой - вторую, и при явном обновлении зависимости проводить осознанное тестирование

                              +4
                              Во многом согласен с автором. Но всё же главное проблемой микросервисной архитекутры является соблюдение косистентности.
                              Давайте честно, *большинство* микросервисов пишется без какой-либо оглядки хотя бы на идемпотентность, не говоря уже о согласованном откате, «если что-то пошло не так». И тут нет исключений. Я это видел даже в Яндексе, хотя вроде как и собеседуют сильно, но на деле все пишут кучу микро-какашек.
                                –1

                                Оставаясь в вашей терминологии:
                                микрокакашки когда они становятся критическими, куда проще выкинуть и заменить на менее пахучее, чем одну большую, размазаную на весь бизнес много лет назад.
                                Чувствуете разницу? ;)

                                  0

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

                                  0

                                  Я бы добавил еще следующие плюсы-минусы микросервисов.
                                  Плюс:


                                  • (на мой взгляд) Легче держать в голове 10 маленьких микросервисов, чем одно огромное приложение.

                                  Минус:


                                  • Запуск микросервиса — это, по-хорошему, запуск приложения, для которого нужно применять процесс Launch Readiness Review (в разных компаниях называется по-разному, но не суть), и запуск из 2-3 дней превращается легко в 2-3 недели. Хотя это недостаток относительный.
                                    0
                                    нам приходится разрабатывать протоколы общения микросервисов, а составить хороший протокол — это отдельная сложная задача.

                                    дык берите уже готовые решения, не?
                                      +3
                                      Микросервисы это всегда про масштаб — масштаб проекта, масштаб команды, масштаб нагрузки.

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

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

                                      Самое читаемое