Предлагаю поговорить о том, когда нужны микросервисы, а когда нет. Спойлер: это зависит от проекта.

У нас, разработчиков программного обеспечения, довольно интересная профессия. Мы можем спокойно кодировать целыми днями, а затем прочитать статью о чём-то — и она подвергает сомнению всю нашу работу, потому что какой-нибудь Netflix сказал XYZ.

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

Вы не Google (если только вы не Google)


Когда мы читаем HackerNews и другие новостные сайты, то часто видим технические сообщения от Google, Netflix, Amazon и Facebook, и они любят говорить о том, сколько сотен или тысяч сервисов они запускают. Они говорят о преимуществах всё делать по-своему. Это тенденция последних нескольких лет.

Но давайте посмотрим правде в глаза. Вряд ли у вас в наличии 1000 разработчиков, которые работают над массивным проектом с более чем 10-летней историей.

Просто потому, что Google делает это, не означает, что вы тоже должны делать это.

Мы работаем в совершенно другой галактике. Google сталкивается с проблемами, с которыми мы, вероятно, никогда не столкнёмся, но в то же время мы можем делать вещи, которые Google не может.

Как начинается большинство программных проектов?


Многие проекты начинаются с одного человека, который делает всю работу. Есть миллион примеров, но давайте посмотрим на Shopify. Изначально сервис закодировал Тобиас Лютке (он был основан на Ruby on Rails и до сих пор, кстати, работает на «рельсах»).

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

Чёрт, нет. Я не присутствовал при разработке первой версии Shopify, которая изначально была просто интернет-магазином для сноубординга, но если Тобиас похож на меня (типичный разработчик), то процесс выглядел примерно так:

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

Это может показаться очень простым циклом, но мне потребовалось около 20 лет программирования, чтобы понять, насколько он глубок.

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

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

Поговорим об абстракциях кода


Как разработчики, мы все слышали фразу «DRY: don't repeat yourself», и в целом это разумный совет не делать работу повторно. Но часто её стоит сделать.

Её стоит повторить, когда вы пытаетесь абстрагировать что-то без полного понимания и создаёте то, что называется неполной абстракцией (leaky abstraction).

Я обычно выполняю работу трижды, прежде чем вообще ПОДУМАТЬ о рефакторинге какого-то кода и удалении дублей. Часто лишь после 4-го или 5-го раза я принимаю какие-то меры.

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

Уровни абстракции, от встроенного кода до внешних библиотек:

  1. Написать встроенный код.
  2. Продублировать код в нескольких разных местах.
  3. Извлечь продублированный код в функции и т.д.
  4. Некоторое время использовать эти абстракции.
  5. Посмотреть, как этот код взаимодействует с другим кодом.
  6. Извлечь общую функциональность во внутреннюю библиотеку.
  7. В течение длительного времени использовать внутреннюю библиотеку.
  8. Действительно понять, как все части собираются вместе.
  9. Создать внешнюю библиотеку (open source и др.), если это имеет смысл.

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

«Рельсы» — отличный пример. DHH (автор Rails) не проснулся однажды и сказал: «Ой! Пора создать директории models/, controllers/ и views/!».

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

Это идеальный шторм очень хорошо обкатанных (читай: не теоретически разработанных) абстракций в сочетании с языком программирования, который позволяет написать привлекательный код. Это также объясняет, почему почти все фреймворки типа «Rails, только на языке XYZ» не работают. Они пропускают ключевые компоненты цепочки абстракций и думают, что могут просто дублировать Rails.

От абстракций к микросервисам


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

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

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

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

Не думаю, что кто-то назовет их маленькими, хотя они и не работают в масштабе Google.

Shopify зарабатывает $17 млн в месяц на монолите


По состоянию на середину 2018 года Shopify публично объявила, что на их платформе работает более 600 000 интернет-магазинов.

Shopify — это приложение SaaS, у которого самый дешёвый тариф составляет $29 в месяц, и у меня такое ощущение, что многие компании выбирают тариф $79 в месяц. В любом случае, даже если 600 000 клиентов использовали самый дешёвый план за $29, это доход $17,4 млн в месяц только от SaaS-направления их бизнеса.

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

Я хочу сказать, что можно зайти ОЧЕНЬ далеко, не спускаясь в кроличью нору микросервисов. Не создавайте микросервисы просто так.

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


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

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

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

Стоит ли овчинка выделки?


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

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

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

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

Их продукт больше ориентирован на крупномасштабные приложения (понятно почему), но также работает и для небольших проектов. Я недавно услышал о них, потому что они были представлены на Cloud Field Day 4.

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

Заключительные мысли


В основном, я написал эту статью по двум причинам:

Во-первых, две недели назад я посетил Cloud Field Day 4 и случайно поучаствовал в групповом подкасте на смежную тему. Он должно выйти через несколько месяцев, но здесь я хотел подробнее остановиться на некоторых моментах.

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

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

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

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

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

Что вы думаете об этом? Дайте знать в комментариях.

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


  1. AbstractGaze
    21.10.2018 21:19

    Я не программист, но для себя читал недавно «Создание микросервисов. Сэм Ньюмен» [2016].
    Собственно одна из мыслей — чтобы создать микросервисы — предварительно надо создать монолит, и если уже надо — тогда будет видно на какие сервисы разбивать.
    Просто интересно кто эти люди, которые вроде как программисты, но начинают делать сразу с микросервисов не видя в целом как оно работает и где надо делить?


    1. fiftin
      21.10.2018 22:00
      +1

      Вы прочитали 1 книгу и делаете выводы. Есть очевидные места где надо делить. Просто не надо впадать в крайности.


      1. AbstractGaze
        22.10.2018 12:06

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

        Знать надо или нет разбивать, и если надо то как правильно — это и есть дорасти.


        1. fiftin
          22.10.2018 14:31
          -2

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


          1. fiftin
            22.10.2018 14:32

            Или, аналогично. Пользователь загружает 3D модель, для неё нужно срендерить превьюшки. Ну не будете же вы это делать в томже приложении?


            1. fiftin
              22.10.2018 14:40

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


            1. Valle
              22.10.2018 17:26
              +1

              Почему нет?


              1. ppl2scripts
                23.10.2018 19:08

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


                1. Valle
                  24.10.2018 02:03

                  И что? Если это не главная задача то наверное нагрузка на рендер будет меньше чем на все остальное. Особенно когда посетителей не более тысячи в час.


                  1. fiftin
                    24.10.2018 09:55

                    Откуда вы знаете какую модель загрузит пользователь и сколько она будет рендериться? Если у вас виртуальный сервер 2 vCPU, 4 GB RAM и 3 пользователя начнут одновременно загружать сложные модели, то ваш сервер встанет на какое-то время (под превьюшками я имею в виду полноценные картинки нормального размера, а не 100x100).
                    Вместо этого логично отсадить рендер на отдельный сервер и рендеринг ставить в очередь. И даже если он встанет раком, это никак не повлеяет на работу всего сайта.


          1. korkholeh
            24.10.2018 13:23

            Почему это очевидно? Это прекрасно может работать в рамках монолита.


            1. fiftin
              24.10.2018 13:39
              -1

              Пользователь загрузил 20-и минутный видео файл в качестве 1024p. Его нужно предобразовать в видео меньшего разрешения: 720p, 480p и 360p. Какой алгоритм будет в монолитном приложении?


        1. altrus
          22.10.2018 20:32

          Откуда по вашему взялись «очевидные места»?

          Из опыта


    1. maxzh83
      21.10.2018 22:03
      +1

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


      1. fiftin
        21.10.2018 22:16

        Также можно сказать про ООП, ФП и другие подходы. А может просто кто-то не хочет говнокодить?


        1. nsinreal
          21.10.2018 23:07
          +2

          Не хотеть говнокодить и не говнокодить — две большие разницы.


          1. fiftin
            21.10.2018 23:28

            Это да. Но без первого второго не получится.


            1. nsinreal
              22.10.2018 00:11

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


        1. maxzh83
          22.10.2018 10:05

          Также можно сказать про ООП, ФП и другие подходы

          Конечно можно
          А может просто кто-то не хочет говнокодить?

          Как говнокод связан с микросервисами? Микросервисы — это про архитектуру. А как она реализована — это уже другой вопрос. Говнокод с равной вероятностью может быть как в монолите, так и в микросервисах.


          1. fiftin
            22.10.2018 10:23
            -1

            Если впихивать невпихуемое в 1 монолитное приложение, то код приложения превратится в говнокод. Архитектура помогает этого избежать.


            1. maxzh83
              22.10.2018 10:31
              +2

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


            1. RPG18
              22.10.2018 11:04

              ООП и ФП это попытки справится со сложностью декомпозицией на меньшие куски.
              Если микросервисы это единственный метод для декомпозиции, то получится как на


              Molonithic vs Microservices

              image


              1. boblenin
                22.10.2018 20:17

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


    1. nsinreal
      21.10.2018 23:38

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


      1. saterenko
        22.10.2018 11:48

        Мне кажется, это просто мода… Типа мы такие современные, сейчас внедрим микросервисы с аджайлом и всё сразу взлетит…

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

        Если же коммуникация между «сервисами» должна быть исключительно быстрой, лучше сделать монолит… У меня был опыт, когда в хорошем продукте всё равно пришлось несколько сервисов слить в монолит, потому как так работало лучше…


    1. jetcar
      22.10.2018 08:10
      -1

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


      1. boriselec
        23.10.2018 08:54

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


        1. jetcar
          23.10.2018 09:20

          да! если написано хорошо то делается это всё легко и быстро


      1. alsii
        23.10.2018 14:33

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

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


    1. Berkof
      22.10.2018 08:12
      +1

      Никогда не говори никогда… ну и в целом не надо слишком сильно обобщать… Если разработчик привык фигачить микросервисы, то может быть вполне нормальной идеей писать сразу на микросервисах. Просто некоторые вещи сразу удобно выделять в микросервисы (например — КЛАДР классификатор, который по отдельности никому нафиг не нужен ни в одном проекте, но в целом компании нужно, чтобы все адреса задавались в едином формате), сервис отправки сообщений (sms, email, telegram) тоже никогда не влазит ни в один из сервисов компании, но оповещения клиентам может слать биллинг, система мониторинга сети или отдел маркетинга и все они хотят слать сообщения без заморочек и по тому каналу, который пользователь указал как приоритетный для связи… да тонны их. Ну а если непонятно «куда приткнуть эту фичу» или «она временная» или вообще «мы тут быстро на коленке накидаем, потом решим что с ним делать», то пусть будет один «микро» сервис, в котором, например, бизнес-логика и всё вот это вот непонятное… Как назвать получившуюся архитектуру с 1-2 кучами ака монолитами и обвязкой из нескольких микросервисов я не знаю, но обычно получается что-то подобное.


      1. mayorovp
        22.10.2018 09:04

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

        Микросервисная архитектура строится по-другому, там монолиту просто нет места.


      1. pesh1983
        22.10.2018 09:22

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


        1. Singaporian
          22.10.2018 10:34
          -1

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


    1. VolCh
      23.10.2018 08:54

      По факту сейчас многие так называемые монолиты являются представителями сервисных архитектур. Очень часто в этих монолитах есть выделенные сервисы типа СУБД или веб-сервера для статики и маршрутизации. Чем какой-то, nginx решающий одну задачу раздачи статики для веб клиентов не просто сервис, а микросервис?


  1. JPEG
    21.10.2018 22:02
    +2

    В мире nodejs есть одна реальная техническая предпосылка к тому, чтобы пораньше распилить приложение как минимум на две части: однопоточность. Если смешать в одном процессе (небольшом кластере) разнородную по потреблению процессора нагрузку, то можно добавить совершенно лишних задержек простым для вычисления задачам за счет более сложных, который будут блокировать event loop. Очевидный пример вынос серверного рендеринга в отдельный воркер/процесс/микросервис.


    1. nsinreal
      22.10.2018 00:06
      +1

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


      1. fiftin
        22.10.2018 00:31

        Это не микросервисы. Но это же уже и не монолит, верно? В статье рассматриваются 2 крайности — монолит или микросервисы. Но есть же еще среднее между ними.


        1. nsinreal
          22.10.2018 00:54

          По моему мнению, это все еще монолит. Это конечно же, спор о терминах, но давайте просто определимся с терминами.

          Вот у меня есть монолитное API-приложение с in-memory database (это просто пример, ок :-)).

          Я заменяю in-memory database на чужую внешнюю бд, которая имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
          Я добавляю к приложению чужой внешний кэш, который имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
          Я добавляю к приложению чужой фулл-текст (эластик, к примеру), который имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
          Я добавляю к приложению балансировку нагрузки на одинаковые инстансы, которые не имеют возможности обмениваться данными, но могут хоститься на отдельном сервере. Приложение перестало быть монолитом?
          Я добавляю к приложению сервис авторизации, который выношу на отдельный сервер и который может обмениваться с основным приложением. Приложение перестало быть монолитом?


          1. fiftin
            22.10.2018 01:38

            Файлы вы храните в S3. Видео перекодируете в AWS ElasticTranscoder. RTMP транслируете через Red5. 3D модели рендерите SolidWorks. Email-ы рассылаете через SES. Картинки конвертируете ещё чем-то. И т.д.
            Да, на мой взгляд, это уже будет сложно назвать монолитным приложением.


            1. nsinreal
              22.10.2018 02:02

              А что, если у меня всего этого нет, потому что не нужно? Ладно, не суть


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


              Я так не играю. Извините, но имхо, то, что вы описываете далеко от общепринятого понимания микро/нано-сервисов.


              1. fiftin
                22.10.2018 10:31

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


          1. Myateznik
            24.10.2018 10:59
            +1

            Как бы вам сказать ответы: «Да, монолит» и «Нет, не монолит» одновременно смотря с какой стороны смотреть.

            Ответ «Да, монолит» со стороны пользователей вашего API-приложения — для них ваше API-приложение условно «чёрный ящик» и внешне он самостоятелен и независим.

            Ответ «Нет, не монолит» должен быть с вашей стороны т.к. вы знаете строение этого «Чёрного ящика», а следовательно для вас он уже либо «Белый ящик», либо «Серый ящик».

            Посмотрите на следующую цепочку: Монолит > SOA и Микросервисы > Библиотеки и Модули > Классы и функции.

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

            Рассмотрим ваше API-приложение:

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

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

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

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

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

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

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

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


  1. Web_Proger
    21.10.2018 22:21
    +2

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

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


  1. nsinreal
    21.10.2018 23:29
    +1

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


    1. fiftin
      21.10.2018 23:37

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


      1. nsinreal
        21.10.2018 23:59
        +1

        Вы верно вспоминаете о том, что бд/кэш/elastic тоже вводят дополнительные сетевые заддержки.


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


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


        Но есть еще один важный момент. Вводя микросервисы вы увеличиваете длину цепочки пересылки данных. Причём в худших случаях, если перестать следить, то цепочка увеличится не на один микросервис, а на кучу.


        1. fiftin
          22.10.2018 00:18

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


          1. nsinreal
            22.10.2018 00:27
            +1

            Почему вы считаете, что монолит — это дорого для начинающего проекта?


            1. fiftin
              22.10.2018 00:34

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

              Я уверен что любое приложение можно на начальном этапе разделить как минимум на 2 части:
              — с состоянием
              — без состояния

              На часть без состояния обычно приходится основная нагрузка. И эту же часть легко масштабировать. Для этого, например, в AWS/Azure существуют готовые решения: auto scaling groups / scale sets. Это позволяет держать 1 меленький сервер, а в пиковые нагрузки запускать дополнительные.


              1. nsinreal
                22.10.2018 00:45

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

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

                Если вы испытываете проблемы с поступающей нагрузкой, то у вас есть возможность поднять кучу инстансов и сделать балансировщик нагрузки. Многие приличные бд имеют возможность создавать read replica. Вы также можете вынести отдельные тяжелые операции в фон на отдельный сервер с помощью очередей, если это возможно (если что, это вовсе не микросервисы).

                Почему описанные стратегии не подходят?


                1. fiftin
                  22.10.2018 00:55

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

                  Но это же уже будет не монолит?

                  если что, это вовсе не микросервисы

                  еще раз, я не говорил про микросервисы, я имел в виду минисервисы.


                  1. nsinreal
                    22.10.2018 01:02

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

                    еще раз, я не говорил про микросервисы, я имел в виду минисервисы.
                    Разница только в объеме кода или есть еще какая-то разница?


              1. maximw
                22.10.2018 00:46
                +1

                Нет, это не правда. Размещение по серверам и монолитность никак не связаны. Можно сделать несколько копий монолита (воркеров) на слабых серверах за балансировщиком, а можно все микросервисы посадить рядом на один сервер.


                1. fiftin
                  22.10.2018 00:49

                  Сделать несколько копий монолита возможно только для очень простого монолита. Я даже таких приложений и не встречал.


                  1. nsinreal
                    22.10.2018 00:54

                    Почему вы так считаете?


                    1. MIKEk8
                      23.10.2018 16:34

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

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


                      1. nsinreal
                        23.10.2018 18:08

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

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

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


                        1. MIKEk8
                          23.10.2018 18:17

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

                          И по сути БД или MQ это микросервис.


                          1. nsinreal
                            23.10.2018 19:33

                            Оверхед тут в том, что приходится использовать лишнее хранилище, хотя если это было одно приложение то можно было бы эти данные хранить и сортировать в памяти, без использования очередей.
                            С очередью в памяти очень трудно добиться либо гарантий persistance, либо гарантий exactly-once. Все еще оверхед?

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

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


                    1. fiftin
                      23.10.2018 20:49

                      Я имел в виду что я не участвовал в разработке веб-приложения, которое можно было бы реализовать монолитным (UPDATE: правильнее сказать, целесообразно, потому что если сильно захотеть, можно в посмос улетель). Мне приходит в голову только онлайн-магазин, сайт на wordpress и что-то в этом роде. Более-менее сложное веб-приложение требует разделения на несколько независимых приложений.


                      1. fiftin
                        23.10.2018 21:00

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

                        Сделать несколько копий монолита возможно только для очень простого монолита. Я даже таких приложений и не встречал.

                        их сильно задевают.


                        1. nsinreal
                          23.10.2018 21:06

                          Ваше безаппеляционное заявление привязано к вашему личному опыту. Как мне кажется, именно за это и минусят вас.

                          Но вы мне скажите один момент. Микросервисы в общем-то недавняя тема (если смотреть по взрыву популярности). Как до этого момента люди делали сложные приложения?


                          1. fiftin
                            23.10.2018 21:16

                            Делали немонолитные приложения — сервисы. Просто они были не микро.

                            И продолжают так делать. Может вы скажете что Facebook, Google, VK — это монолитные приложения?


                            1. nsinreal
                              23.10.2018 21:27

                              Пожалуйста, забудьте учебник демагогии. Это реально раздражает.


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


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


                              1. fiftin
                                23.10.2018 21:35

                                Я уверен что они не монолитны.


                                1. nsinreal
                                  23.10.2018 21:43

                                  Хорошо, давайте зайдем с другой стороны. Как разрабатываются сложные приложения вне веба? Тоже сервисы/микросервисы?


                                  1. fiftin
                                    23.10.2018 21:47

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


                                    1. nsinreal
                                      23.10.2018 21:50

                                      Ага. Например, ядро линукса, движок v8, или компилятор достаточно сложного языка.


                                      1. fiftin
                                        23.10.2018 22:09

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


                                        1. nsinreal
                                          23.10.2018 22:13

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


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


                  1. MasMaX
                    22.10.2018 10:55

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

                    И от сложности кода тут ничего не зависит. Разве что у вас такие сложные запросы к БД когда две копии одного приложения будут драться за блокировку таблиц например.


              1. Kroid
                22.10.2018 00:52
                +2

                >Потому что монолитное приложение можно разместить только на 1 сервере.

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

                upd: Опоздал с сообщением, выше уже всё написали.


                1. fiftin
                  22.10.2018 01:01

                  Всегда ли монолитное приложение можно разместить на 6 серверах?


                  1. nsinreal
                    22.10.2018 01:06

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


                    1. fiftin
                      22.10.2018 01:18

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


                      1. nsinreal
                        22.10.2018 01:26

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

                        А если этого нельзя, то приложение сделано рукожопами?
                        Строго говоря, у разработчиков монолита могли быть весомые причины не добавлять возможность запуска на произвольном количестве серверов. Однако в таком случае и о микросервисах говорить бессмысленно.
                        Так что в рамках выбора монолит/микросервисы мы имеем, что такое монолитное приложение спроектировано рукожопами.


                  1. Kroid
                    22.10.2018 01:41

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

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

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

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


                    1. fiftin
                      22.10.2018 01:49

                      Пример, приложение по таймеру делает какие-то действия с базой, например очищает старые записи. Я запустил 10 инстансов и получил 10 очисток, вместо 1.

                      Понятное дело, что можно начать придумывать, типа, запускать таймер только на 1 инстансе, запускать в 10 раз реже и т.п.

                      Но не проще ли сделать отдельное приложение для этого?


                      1. nsinreal
                        22.10.2018 02:09

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


                        1. fiftin
                          22.10.2018 09:29

                          Я где-то сказал про микросервисы? Я просто привожу пример где проще разделить 1 приложение на несколько.


                          1. nsinreal
                            22.10.2018 13:28

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


                            1. fiftin
                              22.10.2018 14:19

                              Вот именно «недостатки монолита по сравнению с микросервисами», а получается наоборт, что у него монолита одни плюсы. Но это неправда


                              1. maximw
                                22.10.2018 23:49

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

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


                                1. ayevdoshenko
                                  23.10.2018 06:21

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

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


                            1. Fortop
                              23.10.2018 13:21
                              +2

                              Зря ведёте дискуссию.
                              Ваш оппонент плавает в темах, что монолита, что микросервисов.


                              Причём ужасно плавает.


                              1. fiftin
                                23.10.2018 20:31

                                Мне вот интересно, такие умные комментаторы дейстиветельно делали что-то серьёзное или только в теории всё знают?

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


                                1. nsinreal
                                  23.10.2018 21:01

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

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

                                  Зы: вы же не думаете, что люди защищающие монолит защищают отсутствие модульности?


                                  1. fiftin
                                    23.10.2018 21:04

                                    Я думаю что они защищают чувство собственного достоинства.

                                    Да, я не эксперт в микросервисах, я никогда с ними не работал и по-этому стараюсь их не упомянать. Но что такое монолит я представляю.


                                    1. nsinreal
                                      23.10.2018 21:10

                                      Вот это лол. Вы неявно обвиняете чувака в недостатке практики. Но при этом:
                                      1) вы не представляете как масштабировать монолит;
                                      2) сами не имеете практики участия в проектах с архитектурой похожей на микросервисную.

                                      Вы не находите в этом ничего смешного?


                                      1. fiftin
                                        23.10.2018 21:12

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

                                        А вы имели дело с микросервисами? Несмешо, если нет.


                                        1. nsinreal
                                          23.10.2018 21:19

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


                      1. Kroid
                        22.10.2018 02:13

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

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

                        >Но не проще ли сделать отдельное приложение для этого?

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


                      1. RPG18
                        22.10.2018 08:59

                        Но не проще ли сделать отдельное приложение для этого?

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


                      1. maximw
                        22.10.2018 11:33

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

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

                        Никакой разницы в этом смысле между микросервисом и монолитом.


                      1. nightwolf_du
                        22.10.2018 11:42

                        А почему бы для задачи очистки старых записей не сделать job-у на базе?
                        Всегда есть больше 1го решения, и у всех свои плюсы/минусы


                    1. fiftin
                      22.10.2018 01:52

                      Еще 1 пример, для nodejs. Чат на WebSocket'ах. Запустите его на 2 серверах :-)


                      1. Kroid
                        22.10.2018 02:01

                        У того же редиса есть pub/sub, в нем и хранить состояние. Тогда экземпляров nodejs можно хоть десяток наплодить.


                        1. fiftin
                          22.10.2018 02:05
                          +1

                          Да, плохой пример.


                      1. mayorovp
                        22.10.2018 07:06

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


                        1. fiftin
                          22.10.2018 10:05

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


                          1. mayorovp
                            22.10.2018 10:09

                            Так чем же принципиально отличается взаимодействие двух приложений от взаимодействия двух серверов? В обоих случаях используется обмен сообщениями.


                          1. nightwolf_du
                            22.10.2018 11:44

                            Ничем особо не отличается от синхронизации процессов после fork()


                    1. fiftin
                      22.10.2018 01:57

                      Ещё пример. Вам нужно сконвертировать видео загруженное пользователем. Вы будете его налету конвертировать монолитным приложением?

                      Нормальный подход — сделать для этого отдельный сервис.

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


                      1. Kroid
                        22.10.2018 02:04

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


                        1. fiftin
                          22.10.2018 02:09

                          Ок, восстанавливаемая загрузка (upload) больших файлов.

                          Update: да, тоже можно через общую фс. Пойду спать)


                          1. nsinreal
                            22.10.2018 02:12

                            А в чем ключевые различия этой задачи при монолите и при микросервисной архитектуре?


                            1. fiftin
                              22.10.2018 02:20

                              Микросервисы:


                              Монолит (resumable upload не прокатит):


                              1. nsinreal
                                22.10.2018 02:23

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


                                1. fiftin
                                  22.10.2018 02:28

                                  Сервисов можно наплодить хоть сколько, при этом иметь 1 сервер для закачки файлов.


                                  1. nsinreal
                                    22.10.2018 02:42

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

                                    Но ваши примеры становятся все лучше и лучше


                              1. MasMaX
                                22.10.2018 10:57

                                А что мешает на второй картинке вперед еще один балансер поставить?


                                1. fiftin
                                  22.10.2018 12:25

                                  Он там и подразумевается, только вот если балансировщик будет случайно выбирать сервер, то закачка будет начинаться каждый раз с 0 с вероятностью 1 / кол-во_серверов.


                                  1. MasMaX
                                    22.10.2018 12:32

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

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


                                    1. fiftin
                                      22.10.2018 15:01

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


              1. Mishiko
                22.10.2018 12:11

                монолитное приложение можно разместить только на 1 сервере

                — не правда, кластеризация и балансировка запросов возможны и на монолите


      1. viiy
        22.10.2018 11:55

        Сравнение IO разных подсистем
        Странно что никто до сих пор это не кинул
        gist.github.com/jboner/2841832


        1. fiftin
          22.10.2018 12:01

          Вы про это:

          Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms


          Между Калифорнией и Нидерландами 150ms. А точто такое же внутри одного датацентра?


          1. RPG18
            22.10.2018 12:11

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


            1. fiftin
              22.10.2018 12:20

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


              1. RPG18
                22.10.2018 12:24

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


              1. nsinreal
                22.10.2018 13:21

                Я видел приложение, которое гоняло между микросервисами файлы объемом 1-100 мегабайт в рамках одного API-запроса десяток раз. Даже на локальной машине это жутко тупило. Но это эпик случай.

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

                Это вовсе не пренебрежимо малая задержка.


          1. viiy
            22.10.2018 12:32

            Round trip within same datacenter = 0.5ms
            А если учитывать tcp handshake, кучу промежуточных роутеров, фаерволов, несколько уровней балансировщиков, можно получить скорость, которую совсем не ожидаешь, особенно если микросервис однопоточный, не имеет очередь. Тут же всплывают вещи о которых надо думать, потери пакетов в сети, лимиты на процесс (которых можно не достичь при локальных сервисах) и прочее-прочее. И в итоге может оказаться, что сравнивая производительность проекта построенного на микросервисной архетикруте и монолита, разница получается не в пользу микросервисов, при большей суммарной производительности серверов где работают микросервисы.


            1. fiftin
              22.10.2018 13:06

              tcp handshake: не обязательно создавать TCP подлючение на каждый запрос.
              кучу промежуточных роутеров, фаерволов: например в AWS/Azure есть опция (Accelerated Networking) которая отрубает фаервол.


              1. viiy
                22.10.2018 13:32

                А я и не спорю, если вы заметили
                Я привел сравнительную таблицу только для одной цели, оценить задержки разных подсистем. Разбивая монолит на микросервисы вы добавляете значительную сетевую работу, которая медленнее всего, даже если это 10G. Приведение форматов обмена между микросервисами тоже необходим, а протокол общения добавляет кол-во возможных исключений. Что делать при отсутствии сети, потере пакетов, недоступности какого-либо сервиса, ошибок ответа, перегрузке вм-ки где работает сервис. И это только сетевая часть. А если немного поофтопить, и коснуться деплоя, то возникают вопросы версионности, внедрение фич касающийся сразу нескольких сервисов, обратной совместимости (при rollback и смене версий), сложности CI/CD, балансировке, сервис-дискавери. Повторюсь, я не спорю, просто разбивая на микросевисы, вы выносите изнутри наружу всю сложность связности. Когда то это оправданно, но чаще нет.


    1. jakobz
      22.10.2018 11:35
      +2

      В статьях про микросервисы, забывают очень много важных моментов.

      Например что если данные лежат в двух отдельных БД — невозможно гарантировать их консистентность. Ну типа такую операцию нельзя выполнить транзакционно:
      personsSvc.fire(id = 123);
      workplaceSvc.free(id = 123);

      Или что не получится по-человечески сделать распределенный join на данных из двух сервисов, типа
      select *
      from svc1.persons p
      join svc2.tasks t
      where p.name like 'ivan%' and t.name like 'do %'

      Такого плана мелочи ведь меркнут перед всеми неоспоримыми плюсами микросервисов.


      1. GreenNinja
        22.10.2018 12:53

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


        1. jakobz
          22.10.2018 13:32

          Ну как не так-то?

          Распределенные транзакции невозможны даже теоретически по CAP, а условный 2-phase commit — дает какую-никакую соломку, но средней руки разработчик никогда его по-человечески не сделает, а средней руки архитектор и аналитик — никогда этого «маленького нюанса» не учтут. В результате постоянная история когда что-то там «не прососалось», и руками что-то там в БД лазают и правят.

          Распределённый join теоретически возможен — таки никакой разницы с БД вроде как нет — алгоритм будет такой же: hash join или inner loop там. Но когда это делается внутри БД — с локальным диском, кешем, и умными опытными разработчиками БД сделанное — это одно. А когда поверх REST-сервисов джунами — это совсем уже другое. Там же приходится городить кеши или сервисы-аггрегаторы какие — и хана перформансу и консистентности.

          Ну и при этом всём, я регулярно вижу всяких архитекторов, которые реально топят за «давайте выделим Person Service и будем туда ходить из всех аппов в стиле GET svc/people/123». А иногда этим идиотам даже дают реально делать так систему, потому что модно. Весь этот проект, есстесственно, жостко факапится. И по жопе за это этим идиотам даже не выдать. Да, можно уволить их с позором. Но они же потом пойдут и устроятся «с опытом построения микросервисных архитектур» в другое место. Потому что модно. И даже может и не поймут что проект факапнулся от их глупости.

          Поэтому я аггресивно против популяризации микросервисов. Еще раз — не против самого паттерна, а против его пополяризации. Людей, которые могут обоснованно принять решение юзать микросервисы — очень мало, там должен быть опыт архитекторства и разработки лет в 10 хотя бы. Эти люди сами как-нибудь решат. А для остальных всех — гораздо лучше будет если по-умолчанию в голове установка «микросервисы — плохое решение в 99% случаев».


          1. SergeyMax
            22.10.2018 13:48

            Распределенные транзакции невозможны даже теоретически по CAP,

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


            1. FlameDancer
              23.10.2018 08:55

              Ну хорошо, если не по CAP так по Two General's Problem
              Обычно CAP и Two Generals из одной области, находятся одновременно человеком, когда проблема до него доходит, и весьма возможно что одна из них выводиться из второй.
              Вообще jacobz написал хорошо.


      1. thecoder
        23.10.2018 12:46

        Транзакционное поведение в микросервисах делается через общую шину и ключи идемпотентности. Если облом на одном из сервисов, другие участники получают сигнал "сделай обратную операцию". Более того, действия могут быть очень разветвленными, на много экранов, если бы это было внутри хранимой процедуры. Ну а джойны с like%, это само по себе узкое место производительности и маркер костыля. А ведь можно вместо джойна кинуть запрос на десяток сервисов(например поисковый) и асинхронно склеить. Яндекс вон склеивает целую пирамиду из результатов метапоисков.


        1. Kroid
          23.10.2018 14:01

          А если облом в общей шине?


          1. ayevdoshenko
            23.10.2018 14:32

            То же самое, что и «если ядерный взрыв случится». Шина попадет в рай, а микросервисы — просто сдохнут: ))


            1. Kroid
              23.10.2018 15:22

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


              1. ayevdoshenko
                23.10.2018 15:54

                Это была шутка юмора. Хотя в ней и не только юмор — вы спрашиваете про проблемы в шине — но это равнозначно, что спросить: А если сервер откажет? И что ты будешь делать со своим монолитом, Илон Маск? Это же ерунда — эти отказы не следствие выбора архитектурного решения. Из-за чего шина может отказать? Из-за проблем кода самой шины? — Ну так это плохая шина, и в монолите будет проблема, если его «внутренняя шина» кривая. Или проблема связана со связью? — Ну так и монолит без сети скорее всего бесполезен как вещь в себе в современных-то реалиях, да и микросервисы городить для не сетевого приложения смысл какой?

                Поэтому я бы не скидывал и ядерный взрыв как фактор в таком уж случае.


                1. Kroid
                  23.10.2018 16:46

                  Нет, подождите. Есть важное различие.

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

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

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

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


                  1. thecoder
                    23.10.2018 19:33

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


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


                    В простонародье есть "золотое правило микросервиса" — любой микросервис можно выкинуть и переписать с нуля за 2 недели не ухудшив.


                  1. ayevdoshenko
                    24.10.2018 07:04

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


                    1. Kroid
                      24.10.2018 08:53

                      Да, я так и писал — «в распределенном приложении».

                      >каковыми могут быть и монолиты — как несколько инстансов на разных узлах

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


                      1. ayevdoshenko
                        24.10.2018 09:46

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

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

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


        1. jakobz
          23.10.2018 17:53

          А ты где-то видел схему с «делай обратную операцию» работающую реально? Я вот как-то не верю что ее можно руками сделать вообще надёжно, даже для простых случаев.
          Да даже если так сделать — все равно ж это не ACID.

          И про like% я и не говорил. Я говорил что обычный джоин нельзя сделать на JSON/REST-сервисах без слёз. Ну типа есть такие API:
          users.svc/get?age=23&city_id=2,3,1
          locations.svc/get?i=1,2,3&country='RU'
          Как вытащить всех пользователей с age=23 из городов с country='RU'? Вынуть все города России, и передать их ID в users? Или вынуть всех пользователей с age=23, вынуть их city_id и передать в locations?


          1. thecoder
            23.10.2018 19:16

            Как вытащить всех пользователей с age=23 из городов с country='RU'?

            Никак. Это пример архитектуры курильщика. Еще и на мобиле часто это все пытаются через REST дергать, чтобы собрать интерфейс, по 20 запросов на экран. Сквозные данные (единый набор id, общие структуры) не должны летать между сервисами.


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


            … где-то видел схему с «делай обратную операцию» работающую реально?

            Гарантий 100% никто дать не может и бывают необратимые действия. Это надо индивидуально рассматривать. В редакторах undo реально работает и сложность там не запредельная.


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


    1. Mishiko
      22.10.2018 11:53

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


      1. stul5tul
        23.10.2018 21:53
        -1

        усложняют инфраструктуру (часто требуя дополнительного сетевого оборудования и ПО типа nginx, для проксирования, балансировки).


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


  1. Miron11
    22.10.2018 00:57
    -4

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

    К сожалению в Microsoft Visual Studio кнопки «приготовить пакет для инсталляции на Microsoft Windows Server 2016» не оказалось, а без кнопки выполнять поиск по соответствию пакетов библиотек платформе разрабочик отказалась, на основании того, что это потребует от неё работать сверхурочные.

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

    Средства на освоение Microservice были освоены и выплачены, работа была не сделана, а недостаток компетенции инженера свалили на отсутствие кнопки в Microsoft Visual Studio.

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

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

    «А я сра-ал на Вашего Ленина
    И на весь Ваш савейський саю-у-усь»

    я спокойно подсчитывал в уме стоимость трех килограммов сельди ( которой говорят нигде не было ) по 2 рубля и 13 копеек за кило, высчитывал среднее арифметическое в расчете на одну рыбу, просчитывал отимальную стоимость покупки, в плане калорий, веса, затрат бюджета с точньстью до 4-го знака после запятой, поправлял на реальную стоимость у прилавка, платил точно до копейки, при чем продавщица не смела пикнуть, запросив 11 рублей 50 копеек за 3,5 кило, и уходил от прилавка, когда следующий покупатель выкладывал уже 13 рублей за ту же покупку, на ответ «а почему он дал меньше», продавщица вежливо отвечала «неа, он дал столько же» а на попытку упорного покупателя, изрядно отдававшего спиртным, настоять на своем вежливо отвечала «а давай подсчитаем, е*лан поганый», чем вызвала взрыв доверия всей очереди криками одобрения и немедленную оплату покупателя, счастливо расстающегося с 3-е кратной суммой, поскольку в пересчете на потерянное время от удовольствия от алкоголя с вожделенной закуской, препирательства были неуместны.

    Если Вы думаете, что в США продавщицы чем — то отличаются от продавщиц СССР, Вы очень глубоко ошибаетесь. В России просто не привыкли прятаться. К моему глубокому ужасу недавно в одном из крупнейших магазинов страны я наблюдал сцену, которую очень надеялся никогда в жизни не увидеть. Пьяный муж, на чистом русском мате, охаживал свою супругу, обслуживающую покупателей, чтобы она не слишком улыбалась, или её дома ждет полный ***.

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

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

    К чему такие вот всемирные обобщения… казалось бы все очевидно. Все было бы очень хорошо, если бы этому самому, которому нужны компьютеры, сервисы, микросервисы и прочая, в общем — то не нужная дребедень, они нужны были чуть меньше. Именно нашему, Русскому… Мы не можем себе позволить не делать. Звезда у нас такая :)


    1. Singaporian
      22.10.2018 10:40

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

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

      Вы это хотели сказать? Тогда вы не правы.
      Любая технология применима в одних ситуациях и неприменима в других. Вообще любая.


    1. DjOnline
      23.10.2018 11:17
      +2

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


      1. tendium
        23.10.2018 14:17

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


      1. Miron11
        24.10.2018 06:57
        -1

        По пунктам:
        1. Docker «это всего лишь виртуальная машина» — нет.
        2. «при чем она» — ответ чуть ниже.
        3. «Микросервис можно и» — нет, нельзя. Сервис, не изолированный от ОС является просто «сервисом». Другое дело, что определение не ограничивает средства изоляции контейнерами. Но то, что изоляция необходима определено совершенно четко.
        4. рыба это пример, компьютеры не нужны, если принять концепцию автора «надо как дешевле, главное чтобы работало» Без компьютеров дешевле, и прекрасно работает.


        1. DjOnline
          24.10.2018 09:45

          >>Сервис, не изолированный от ОС является просто «сервисом».
          Кто такую чушь сказал?
          Та штука, поднятая на IIS, точно такой же микросервис. И это всего лишь вопрос удобства развёртывания и безопасности, в докере он, или нет, или в какой-то виртуальной машине, или на выделенном кластере.


  1. pnovikov
    22.10.2018 05:08

    Квинтессенция статьи: "если вы не понимаете каким боком к вашему приложению приплести микросервисы — спите спокойно, они вам не нужны".


  1. k0nst
    22.10.2018 08:50
    +1

    сервис на базе микросервис архитектуры Docker
    — с каких это пор Docker стал микросервисной архитектурой?


    1. Miron11
      23.10.2018 06:46
      -1

      Реализация microservice Microsoft основана на архитектуре Docker. Вот «reference example»:

      docs.microsoft.com/en-us/dotnet/standard/microservices-architecture
      github.com/dotnet-architecture/eShopOnContainers

      На все остальные вопросы — Яндекс в помощь.


      1. k0nst
        24.10.2018 11:12

        микросервисы и архитектура Docker — вообще никак не связанные между собой вещи. Даже по Вашей же ссылке написано:

        This guide is an introduction to developing microservices-based applications and managing them using containers.


  1. ayevdoshenko
    22.10.2018 09:37

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

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

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


  1. egordeev
    22.10.2018 09:58
    +1

    а вроде с микросервисами нет ничего нового: это идея из философии UN*X, когда каждая программа должна делать что-то одно, но делать это правильно.
    Есть сомнения, что кто-то просто придумал новое слово «микросервисы» для старой и проверенной идеи


    1. Ogra
      22.10.2018 10:17

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


      1. egordeev
        22.10.2018 10:20
        +1

        а разве идея, что каждая программа должна делать что-то одно, но делать это правильно, не архитектурное решение?
        Вроде целая О.С. UN*X создана на основе этой идеи?


        1. MasMaX
          22.10.2018 10:59

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


        1. Ogra
          22.10.2018 11:33

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

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


          1. egordeev
            22.10.2018 11:44
            +1

            а вроде идея микросервисов в том, чтобы разбить одну сложную программу на более простые программы, которые взаимодействуют между собой; или иначе?
            а это вроде и есть есть идеи философии un*x: разделить сложную задачу на простые задачи, а для каждой задачи написать программу, и наладить взаимодействие между программами?
            И почему именно про HTTP?


            1. Ogra
              22.10.2018 11:51

              идеи философии un*x: разделить сложную задачу на простые задачи

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


              1. egordeev
                22.10.2018 12:00

                делать одно — это не делать многое?
                если программа делает многое, то это уже сложная программа или простая программа?


                1. Ogra
                  22.10.2018 12:09

                  Можно ли киянку называть кувалдой?


                  1. egordeev
                    22.10.2018 12:22

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


          1. MasMaX
            22.10.2018 12:10

            Вы немного путаете частное с общим. Микросерисы, написаные на JS тоже умеются общаться через сокеты/pipe по желанию и посылать данные не в json. Просто по HTTP+JSON так проще и поэтому многие так делают.


      1. Singaporian
        22.10.2018 11:05

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

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


        1. nsinreal
          22.10.2018 14:05

          Гм-гм, Джоэл вовсе не топит за использование сырого текста вместо XML. Перечитайте статью.


          1. Singaporian
            22.10.2018 14:10

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


            1. nsinreal
              22.10.2018 14:18

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

              А что видите вы?


    1. maximw
      23.10.2018 00:04

      Могу сказать, что монолиты тоже следуют этой же философии UN*X.
      В каждом своде правил/советов по хорошему коду есть пункт типа «каждый фрагмент кода должен выполнять одну задачу», разумеется, делать это правильно.


      1. egordeev
        23.10.2018 09:50

        а какие, например, монолиты, следуют этой философии?


        1. maximw
          23.10.2018 11:25

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


          1. egordeev
            23.10.2018 11:50

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


            1. maximw
              23.10.2018 13:02

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


            1. TemaAE
              24.10.2018 06:26

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


              1. Kroid
                24.10.2018 09:03

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


                1. TemaAE
                  24.10.2018 09:14

                  Не имел удовольствия прикоснуться к Эрлангу.
                  Если все как вы говорите, то если в куске, который заменили, во время замены проблема возникнет типа «Global apocalypse panic» — она за собой только этот кусочек потянет или всю конструкцию?


  1. ikirin
    22.10.2018 14:01
    +1

    Я для себя решил, что МС стоит использовать (как архитектурный подход), если необходимо создать по-ностоящему распределенное приложение, которое будет работать в облаке, так сказать cloud native. Во всех других случаях нужно 100 раз подумать.


  1. amarao
    22.10.2018 14:12
    +1

    Микросервисы — это как agile. В коде оно никак не проявляется. Повторю, микросервисы — это не алгоритмическое явление, а административное.

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

    «Кто пишет спецификации» — это не архитектурное решение, это административное. И его цель — разделить труд более квалифицированных и менее квалифицированных людей. Более квалифицированные думают про архитектуру, менее квалифцированные реализуют что сказали без необходимости быть визионерами и думать на 20 ходов вперёд.

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

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

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


  1. tendium
    22.10.2018 15:36
    +1

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

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

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

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

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

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

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

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

    Но мы бы не продолжали «ехать» в данном направлении, если бы сервисы несли только проблемы. Кратко перечень выгод:

    — команда начала писать тесты (в старом легаси коде это было почти невозможно из-за повсеместного использования статических функций, синглтонов и нарушение паттернов — например, когда в модели неожиданно для тебя делается бизнес-логика)
    — команда несколько обновилась: те люди, которые были причастны к написанию некачественного старого кода и не смогли приспособиться к новым подходам, были вынуждены покинуть команду
    — ребята (даже самый зеленый юниор) достаточно быстро учатся (если уж не в сфере девопс, так в сфере качественной организации кода и покрытия его тестами), предлагают свои идеи, которые день ото дня всё более близки к реальным потребностям нашего продукта
    — нет необходимости прикручивать сбоку костыли в старом легаси, когда можно написать что-то новое, идеологически более правильное, читаемое, тестируемое, масштабируемое
    — мы начали активно использовать кубернетес в своей архитектуре, что нам позволяет гибко доставлять сервисы на продакшн и масштабировать только необходимое, а не весь монолит сразу
    — нет привязки к одному языку, плюс легче производится апгрейд версии языка (раньше был только php версии 5.3, сейчас есть php 7.2, go и немного nodejs).

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


    1. springimport
      22.10.2018 17:18
      +1

      А мне до сих пор не ясно как вообще работать через api со сколько-нибудь сложными данными. Банально в rest api не заложен join, что выливается в постоянное getAllIds(), request($ids) и назначение результатов. Или вот нужно выбрать всех клиентов у которых есть заказы… это вообще жесть: приходится добавлять динамическое поле и делать выборку по нему. А как иначе?
      Так же в rest api гоняется очень много лишних данных из-за чего запросы по 200-300 мс — норма, хотя никакая это не норма.
      Чтобы хоть как-то упорядочить весь этот ворох запросов даже придумали Swagger который реально выручает.

      Но на горизонте уже виден новый многообещающий подход — graphql.


      1. ayevdoshenko
        22.10.2018 19:05

        Верно — graphql. Избавляет от боли модификации api, кача избыточных данных, разрастания набора эндпоинтов. Запихнул его в свой проект с микросервисами — теперь у меня свой проект с graphql и микросервисами: )))

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


        1. boblenin
          22.10.2018 20:02

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

          Та ситуация, с которой он позволяет бороться очень актуальна для кого-нибудь типа facebook, когда у тебя десятки тысяч независимых разработчиков и все хотят разные срезы данных. При этом в жертву приносится значительный кусок функционала от протокола HTTP (состояния, ошибки, уникальные идентификаторы ресурсов, кэширование, докачка), очень сильно ограничивается инструментарий (вся куча кода написанная для http routing) и появляется необходимость поддерживать еще один слой абстракций. Причем если худшем случае задача — только передача данных, то разработка превращается в написание очередного протокола общения с базой данных (где кстати уже есть тоже не шоколадный, но более распространенный ODATA), а если нет — то корявенький RPC.

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


          1. ayevdoshenko
            23.10.2018 06:07

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

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


            1. boblenin
              23.10.2018 19:14

              > мыслить в концепции graphql,

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


              1. ayevdoshenko
                24.10.2018 06:01

                Да, конечно, речь идет о понимании концепции, а часто у специалиста есть опыт работы с какой-то технологией — и он переносит его целиком на другую, из чего получается натягивание совы на глобус, а по итогу этот специалист говорит: да фигня эта «сова» ваша. Что же касается адаптации задачи к технологии… я сталкивался не раз с тем, что одна и та же задача вполне себе решается несколькими способами, вполне хорошо решается. У каждого решения — свои плюсы и минусы, и тут требуется решить — какой набор плюсов/минусов удобнее. Ну и, конечно, возможно это только если способен эти разные решения создать, чего никогда не будет, если есть предубеждения против чего-то — а по факту это неумение работать с той или иной технологией.


                1. boblenin
                  24.10.2018 14:31

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


        1. VolCh
          23.10.2018 16:30

          в идеале один сервис связан не более чем с двумя другими сервисами, обеспечивая иерархическое дерево

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


          иначе геморрой при изменениях начинает расти экспоненциально как функция от количества связей на сервис.

          я предпочитаю один геморрой на сервис (количество связей в нулевой степени), а не, например, 4 при связи с двумя сервисами :)


          1. ayevdoshenko
            24.10.2018 06:35

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

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

            Вообще же, надо просто понять — откуда есть пошли эти микросервисы. Они ведь появились не только лишь потому, что кому-то вздумалось «поиграть в микросервисы». Микросервисы — это логичный ответ на конкретные задачи. Я выше тут писал про свой пример — у меня есть в проекте задача обслуживания клиента, и есть задача периодического мониторинга неких данных, которые я предоставляю клиенту. Можно обе задачи решать в рамках одного монолитного приложения, но так же хорошо эти две задачи могут работать и по отдельности. У меня нет сильной связанности между двумя этими задачами: то есть сбор (обновление) данных конечно нужен, но если он не увенчался успехом в очередной итерации — клиенту допустимо предоставить на его запрос предыдущие данные. Другая особенность состоит в том, что сбор данных может меняться довольно часто из-за того, что сам источник этих данных изменяется и под него надо подстраиваться — в условиях монолита это будет означать необходимость править весь проект, прерывать обслуживание клиентов при апдейте проекта. А в условиях микросервиса — я могу править сервис более удобнее. Я могу вынести микросервис сбора данных куда угодно — это, кстати, тоже одна из задач проекта, так как наш доблестный РКН любит поиграть в модераторов. Я могу наплодить кучу одинаковых микросервисов, тем самым зарезервировав их, я могу относительно легко добавлять микросервисы с другим типом собираемых данных — конечно же тут придется и принимающую часть изменять для того, чтобы она умела эти данные принять, но вся инфраструктура уже построена — нужны лишь кастомны методы приема и обработки конкретного типа данных.

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


      1. tendium
        23.10.2018 10:25

        Вы правы, и столкнувшись с данной проблемой, я чуть более года назад написал вот такое для php (в случае использования symfony + doctrine): github.com/artprima/query-filter-bundle. Для внутренних потребностей у нас работает весьма неплохо (хотя, конечно, кто-то сейчас скажет, зачем использовать symfony и доктрину для микросервисов, но это мы оставим за скобками). Для использования для внешнего апи нужно, наверное, провести аудит на предмет уязвимостей (на первый взгляд я вижу только возможность делать тяжелые запросы, которые не попадают в индексы).
        P.S. Документация к коду не полна, как всегда :( Например, там не задокументированы алиасы для полей (что позволит скрыть t.tableName за чем-то вроде pinkPony).
        P.P.S. GraphQL, кстати, тоже не спасёт от тяжелых неиндексированных запросов. Вообще, произвольный доступ к данным и практически произвольная фильтрация — это достаточно сложная задача не только со стороны API, но и со стороны безопасности и эффективности.


      1. VolCh
        23.10.2018 16:21

        > Банально в rest api не заложен join

        Что значит «не заложен»? Принципі rest не запрещают вам вытягивать сколь угодно сложные схемы.


        1. springimport
          23.10.2018 16:43

          Не запрещает. На автомобиле наверное тоже можно взлететь если разогнаться до скорости света.


    1. boblenin
      22.10.2018 20:10

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

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

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


      1. VolCh
        23.10.2018 12:37

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

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


  1. boblenin
    22.10.2018 19:52

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

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

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


  1. altrus
    22.10.2018 20:44

    Микросервисы как и многое другое является частью парадигмы «Разделяй и властвуй».
    Вполне имеют право на жизнь при умелом использовании


  1. thecoder
    23.10.2018 13:01

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


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


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


    1. VolCh
      23.10.2018 16:31

      ООП тут особо непричём, скорее нужно изучать DDD