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

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

Например: был очень сложный запутанный монолит, мы его разбили на несколько сервисов, каждый из них выглядит прекрасно, любой сможет разобраться с кодом, но что происходит с окружением? Сложность растет: это и распределенные транзакции, которые нужно журналировать так, чтобы понять, что это одна транзакция; для каждого сервиса прибавляется CI/CD и поставка; схема взаимодействия становится нетривиальной.

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

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

Но как насчет других членов команды?

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

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

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

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

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

О чем еще не говорят


Сложность растет


При использовании микросервисов усложняется инфраструктура. Это связано с тем, что нужно поддерживать работу не одного приложения, а множества сервисов. Нужно мониторить работоспособность всех сервисов, хорошо понимать зависимости сервисов по версиям, иметь CI/CD-планы для сборки сервисов и поставки, механизмы реагирования на выходы сервисов из строя, чтобы не легло всё остальное.

Вроде бы простые вещи, и в монолите мы должны делать всё то же самое. Только в монолите мы работаем над одним приложением, а с увеличением количества сервисов сложность растет, что требует от поддержки более высоких навыков.

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

Но и в них могут быть ошибки, которые придётся чинить. Если с починкой мы справляемся без проблем, то чтобы раскатать изменения по 200—300 сервисам, понадобится время и развитые средства управления. А если понадобится пересобрать сервисы с обновленной библиотекой, а то и вызовы переделать (вот так починили, не предусмотрели), то всё это будет не весело.

Монолит — не большой комок грязи(big ball of mud)


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

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

Так что же использовать?


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

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

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

Простой и понятный код — это не про микросервисы, код априори таким должен быть.

Автоматизация тестирования — это тоже про качество кода.

Автоматизируйте всё, что можно автоматизировать — CI/CD. Наверное, есть такой стек технологий, который очень трудно затянуть в CI/CD, но 99% сборок/поставок можно автоматизировать.

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


  1. vanxant
    31.10.2018 08:24
    +2

    Микросервисы — это естественная реакция разработчиков «средних» компаний на изменившиеся условия. Писать всё своё с нуля могут только крупнейшие игроки (Apple/Google/Microsoft), но и там это считается антипаттерном NIH. А все остальные вынуждены юзать тонны чужого кода от разных вендоров.
    С другой стороны, появление этих ваших гитхабов и гибких методологий привело к rolling release-ам, точнее к отсутствию релизов как таковых. Есть поток отладочных версий библиотек с кучей багов, которые никто не собирается фиксить, а вместо этого просто выкатывают новую, несовместимую со старой версию со своими свежими багами.
    Вы начинаете более-менее крупный проект, берёте свежайшие либы и, пока дойдёте до версии 1.0, выясняете, что ваши либы устарели уже на пару мажорных номеров. С монолитом просто так взять и обновиться нельзя, нужно переписывать кучу кода и заново его тестировать.
    Микросервисы решают этот вопрос тем, что позволяют себя переписать на новой либе или вообще новом языке за те пару месяцев, пока версии ключевых либ считаются «свежими».
    Плата за это — да, налог на девопсов, а также сложноуловимые баги «между» микросервисами, когда непонятно, кому вообще заниматься отладкой.


    1. G1yyK Автор
      31.10.2018 08:40

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

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

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

      Пока переписываем микросервис — либы опять устаревают? тут наверное нужно гнатся не за либами — а найти компромис между «старыми» либами и работающим функционалом.


      1. kaljan
        31.10.2018 09:24

        небольшой сервис тестить всяко легче монолита


        1. G1yyK Автор
          31.10.2018 10:19

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

          Плюс спорный вопрос, что тестить проще. Если монолит целиком переписать и потом его тестировать — то ну его нафиг, так вообще не полетит. А если сделать roadmap для переезда на новую платформу(ради чего мы переписываем), то изменения можно будет да же под бизнесовыми задачам провести и протестировать.


          1. guility
            31.10.2018 11:49

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

            Однако, в целом, вы пишите фактически только про изолированность, документированность и чистоту кода.
            Однако, микросервисы — это уход, в первую очередь, от инфраструктурных проблем.
            Потому что монолит — требует, чтобы одна единственная машина могла предоставить все необходимые пакеты(модули) и все необходимые ресурсы требуемые для решения задачи одновременно.
            Когда речь идёт о каком-нибудь многоуровневом стэке технологий(когда одни библиотеки опираются на кодовую базу других) — все хорошо.
            А вот как только вы используете разноплановые библиотеки из разных технологических стеков — запуск и развертывание монолитного решения становится задачей почти фантастической, т.к. постоянно вылезают противоречивые требования или прямые несовместимости библиотек.
            А вот когда дело доходит до обработки больших данных… ух. Тут микросервисы, каждый из которых должен анализировать свой кусок данных на недорогих инстансах 4+4(4 vCPU+4GB RAM), или давать быстрый ответ для пользователей в своей географической зоне — незаменимы.
            К тому же, в тех же направлениях распределенных вычислений фрагментация пакетов-модулей — гораздо выше, чем в «традиционных» областях, что создаст огромное количество проблем при попытке обновления каких-то библиотек в монолите.

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


            1. sentyaev
              31.10.2018 13:51
              +1

              Однако, микросервисы — это уход, в первую очередь, от инфраструктурных проблем.

              С микросервисами сложность инфраструктуры как раз растет.


              1. VolCh
                31.10.2018 17:36
                +1

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


            1. Bonart
              31.10.2018 18:07

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


              1. VolCh
                31.10.2018 18:14

                Навскидку ещё два: селективный деплой и (в теории) возможность работы в режиме частичного отказа.


                1. Bonart
                  31.10.2018 18:22

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


                  1. Virviil
                    31.10.2018 21:45

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


                    1. stratosmi
                      31.10.2018 22:13

                      как монолит — то либо работает либо нет.

                      может же быть несколько экземпляров.

                      Как может «частично» работать (а вернее «частично не работать») монолит в данном контексте — не понятно.

                      ну например, повреждена БД.
                      операции с ней невозможны.

                      но все что не требует СУБД — успешно работает.


                      1. VolCh
                        31.10.2018 23:29
                        -1

                        Про СУБД уже не совсем монолит. Отказоустойчивое масштабирование тоже не про частичный отказ. А так: ошибка при запуске процесса, какой-нить сегфолт. Все дцать инстансов сегфолтятся. Если такое случится с каким-то неключевым микросервисом, то приложение будет работать пускай и не полностью.


                        1. stratosmi
                          01.11.2018 09:03

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


                          С этим не все так просто.

                          Возьмем конкретный ясный всем пример — интернет-магазин.

                          Не работает хоть что-то из этого: корзина, каталог товаров, оформление товаров, прием оплаты-онлайн. У вас нет интернет магазина.

                          То, что работает при этом уведомление пользователей по СМС, уведомление пользователей по e-mail, полнотекстовый поиск, статьи блога, система рекомендаций товара, веб-сайт в целом — ситуацию не изменяет. Все равно у вас нет интернет-магазина.


                          1. linux_art
                            01.11.2018 09:26
                            +1

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


                          1. VolCh
                            01.11.2018 09:31

                            Слово «неключевым» заметили?

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

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


                            1. stratosmi
                              01.11.2018 09:37

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

                              Формально — да, как бы работает.

                              Но от простого просмотра каталога до реального заказа доходит хорошо если 1 из 1000.
                              Так что падение каталога — это фатально.

                              Слово «неключевым» заметили?


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


                              1. VolCh
                                01.11.2018 09:45

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


                1. mayorovp
                  31.10.2018 19:28
                  +1

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


          1. RPG18
            31.10.2018 12:54

            Если монолит целиком переписать и потом его тестировать — то ну его нафиг, так вообще не полетит.

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


        1. andreyverbin
          31.10.2018 12:46

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


          1. kaljan
            31.10.2018 15:52
            -2

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


            1. bo0rsh201
              31.10.2018 20:10

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


              1. kaljan
                01.11.2018 09:41

                я не до конца понял, как Вы к этому выводу пришли


              1. VolCh
                01.11.2018 09:50

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


          1. VolCh
            31.10.2018 17:36
            +2

            Тестировать сервис проще. Тестировать систему сложнее.


            1. Bonart
              31.10.2018 18:08

              Даже сервис тестировать сложнее, чем модуль внутри монолита, решающий те же задачи.


              1. VolCh
                31.10.2018 18:18

                Вот не факт. Пример: для теста нужна БД, для монолита вам надо создать 500 табличек, для сервиса пускай 10.


                1. Bonart
                  31.10.2018 18:26
                  +2

                  Пример: для теста нужна БД

                  Для теста модуля монолита БД может быть не нужна совсем. Или нужна, но те же 10 табличек. Сервису же для тестов в любом случае надо базу и сетевого клиента.
                  Если для тестов модуля монолита нужны все 500 таблиц, то он плохо спроектирован. Такой же по качеству микросервис также захочет 500 таблиц из базы, которую будет делить еще с 50 микросервисами.


                  1. nApoBo3
                    31.10.2018 20:38

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


                  1. VolCh
                    31.10.2018 23:33

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


                    1. Free_ze
                      01.11.2018 11:48

                      Или для каждого теста писать свои миграции?

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


                      1. VolCh
                        01.11.2018 11:55

                        Я про тестирование монолита из 50 модулей по 10 таблиц на каждый (часто с foreign key между модулями, но замнём). Как в такой ситуации его тестировать? Общий поток миграций накатывать? Привязывать миграции к модулям? Ручками или костылями привязывать к тесту собственные миграции, синхронизируя с обычными? Копировать часть схему из эталонной базы?


                        1. Bonart
                          01.11.2018 11:58

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


                          1. VolCh
                            01.11.2018 12:09

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


                            1. Bonart
                              01.11.2018 14:36

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


                              1. VolCh
                                01.11.2018 14:59
                                -1

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


                        1. Free_ze
                          01.11.2018 12:10

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

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

                          И его так же можно делать тестирование, без остальных модулей («монолита»).


                          1. VolCh
                            01.11.2018 12:16

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


                            1. Free_ze
                              01.11.2018 12:43
                              +1

                              Использование IoC-контейнеров (которые позволяют динамическую конфигурацию) — это довольно распространенная практика для монолитов. Системы плагинов и динамически загружаемые библиотеки — тоже не новый революционный подход. Это требование SRP.

                              ищущий среди своих инстансов тот, где он подключен, и дергающий его по сети

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

                              Это ещё будет монолитом?

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


                              1. VolCh
                                01.11.2018 13:15
                                -1

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

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

                                Вот я более чем уверен, что подавляющее большинство в этом топике говоря о монолите, например, в вебе, имеют в виду что-то вроде: клиент в браузере, веб-сервер, апп-сервер, СУБД, какой-нибудь редис, скорее всего где-то крон в фоне, может даже очередь с воркерами отдельными. Отдельная система анализа логов и мониторинга, автоматического перезапуска при краше. И про всё это говорят «у нас монолит». При это ещё прикладывая усилия для того, чтобы части апп-сервера минимально зависели друг от друга, обновлялись на лету, не загружались пока не нужны и выгружались когда уже не нужны.

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


                                1. mayorovp
                                  01.11.2018 13:27

                                  Вот я более чем уверен, что подавляющее большинство в этом топике говоря о монолите, например, в вебе, имеют в виду что-то вроде: клиент в браузере, веб-сервер, апп-сервер, СУБД, какой-нибудь редис, скорее всего где-то крон в фоне, может даже очередь с воркерами отдельными. Отдельная система анализа логов и мониторинга, автоматического перезапуска при краше. И про всё это говорят «у нас монолит». При это ещё прикладывая усилия для того, чтобы части апп-сервера минимально зависели друг от друга, обновлялись на лету, не загружались пока не нужны и выгружались когда уже не нужны.

                                  Не совсем так. Это не мы говорим "у нас монолит", это приходит фанатик микросервисов и говорит "у вас не микросервисная архитектура? Значит, у вас ужасный монолит!"


                                  1. VolCh
                                    01.11.2018 13:35
                                    +1

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


                1. MikailBag
                  31.10.2018 23:37

                  Берем и суем вместо обычного клиента БД собственный, возвращающий тестовые данные. В чем проблема?


                  1. VolCh
                    31.10.2018 23:40

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


                    1. MikailBag
                      31.10.2018 23:45
                      +1

                      По-моему, модульное тестирование всегда делают с подмененной БД, а e2e с настоящей. Ну а БД вообще не часть приложения.


                      1. VolCh
                        31.10.2018 23:49

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


                        1. MikailBag
                          01.11.2018 13:56

                          Значит вы про е2е тесты.
                          Там по-любому потребуется полная БД и все микросервисы/монолит. И опять с микросервисами сложнее.


                          1. VolCh
                            01.11.2018 14:02
                            -1

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


                            1. Bonart
                              01.11.2018 14:41

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


                              А у модуля никакого WebAPI и тем более базы может вообще не быть. Достаточно обычных ООП-интерфейсов. У монолита WebAPI будут трогать только E2E-тесты.


                              1. VolCh
                                01.11.2018 15:05

                                Поднимать или мокать — отдельный разговор.

                                У модуля может быть любой API в том числе WebAPI, и база своя, ну или свои таблички в общей базе. Вот модуль аутенфикации и авторизации. Ему нужен свой ендпоинт, чтобы браузер или иной клиент стукнулся, ему нужна база, чтобы хранить юзеров, пароли, роли, права и связь этого всего друг с другом. Как вы будете тестировать авторизацию без WebAPI и базы? Как проверите, что, например, роутинг корректно настроен и объекты на базу корректно смаплены? и вообще всё это друг с другом связано. Это ещё не e2e с точки зрения всей истемы, потому что UI не задействован, но это тест WebAPI. Грубо, после его прохождения бэкендера можно на другой модуль или проект переводить, а не ждать пока фронтендеры что-то сделают.


                    1. Bonart
                      01.11.2018 12:01

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

                      Двумя сообщениями выше:


                      Даже сервис тестировать сложнее, чем модуль внутри монолита, решающий те же задачи.

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


                      1. VolCh
                        01.11.2018 12:12

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


                        1. Bonart
                          01.11.2018 14:34

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

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


                          1. VolCh
                            01.11.2018 15:13

                            Вот как модулю авторизации не работать с базой юзеров? Ещё раз, мы обсуждаем эквивалентное тестирование микросервиса по сравнению с эквивалентным модулем монолита. Это значит, что если у микросервиса есть ендпоинт и база, значит и у модуля есть. Если на тесте микросервиса мы проверяем весь флоу от отработки сетевого запроса от клиента до работы с базой, значит и для модуля мы проверяем то же. Мокаете работу с базой при тестировании модуля авторизации — мокайте её и при тестировании микросервиса. Не делаете реальный http-запрос при тестировании модуля, а стучитесь к роутингу как-то напрямую — не делайте его и при тестировании микросервиса, только в нём роутинга можте не быть вообще :)


        1. stratosmi
          31.10.2018 16:34
          +2

          небольшой сервис тестить всяко легче монолита


          Ну вы так же можете тестировать монолит всего лишь юнит-тестами.
          Нет? Хотите интеграционные?
          А почему с микросервисами не считаете нужным интеграционные?
          Потому что это гораздо сложнее?

          Мартин Фаулер хорошо разжевал что не все так просто
          habr.com/post/261689

          И ребята из Фланта
          habr.com/company/flant/blog/427283

          За все приходится платить.
          В том числе и за видимую «простоту деплоя одного сервиса».

          Серебряной пули так все еще и нет.
          Где-то что-то имеет какие-то плюсы. Но имеет и минусы.


          1. kaljan
            31.10.2018 16:37
            -2

            я клоню к тому, что в случае с микросервисами тестов меньше, и нагрузка на их содержание меньше, но нагрузка на инфраструктуру растет


            1. RPG18
              31.10.2018 16:43
              +4

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


              1. kaljan
                31.10.2018 16:56
                -2

                1. Количество тестов у монолита > количества тестов у сервиса, который из монолита выдернули
                2. Если при выдергивании сервиса из монолита сложность только возросла и появилось n^2 интеграций — это корявое выдергивание, надо брать больший кусок


                1. RPG18
                  31.10.2018 17:05
                  +3

                  Количество тестов у монолита > количества тестов у сервиса

                  А теперь возьмите сумму тестов всех микросервисов и сравните с количеством тестов монолита. Тесты пишутся на функционал, функционала при микросервисной архитектуры меньше не становится.


            1. stratosmi
              31.10.2018 16:45
              +1

              я клоню к тому, что в случае с микросервисами тестов меньше, и нагрузка на их содержание меньше, но нагрузка на инфраструктуру растет


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

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

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


              1. kaljan
                31.10.2018 17:01
                -1

                логи спасут мир


                1. RPG18
                  31.10.2018 17:07
                  +1

                  Что-то не спасают. Поэтому появились сервисы для трассировки.


                1. stratosmi
                  31.10.2018 17:19
                  +2

                  логи спасут мир

                  Конечно, конечно.

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

                  И хорошо, если речь идет только об «линейно проходящих» запросах.

                  А если это фоновые процессы, запускаемые при разных условиях? Или если это несколько параллельно порожденных вызовов внутри микросервисной системы?

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

                  Никто не говорит, что в микросервисах невозможно отлаживать в принципе.

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

                  Когда вы переходите на микросервисы — сложность никуда не уходит.

                  Просто из монолита сложность размазывается между микросерисами и связями между ними.

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

                  У микросервисов есть свои преимущества. Которые являются недостатками в монолитах.

                  Но микросервисы вовсе не универсальная серебряная пуля. Так как появляются и новые недостатки. Которые в монолитах не так остры.

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


                1. bo0rsh201
                  31.10.2018 20:13

                  Вместо find usages и проверки всех использований вам надо каким-то образом при любом изменении бегать по графу зависимостей всех ваших сервисов, причём рекурсивно.


        1. Bonart
          31.10.2018 18:03

          Ага, особенно хорошо тестировать End2End


    1. stardust_kid
      31.10.2018 19:50

      • Semver?
      • Не, не слышал.


  1. inf
    31.10.2018 08:37

    Монолит — небольшой комок грязи(big ball of mud)

    Так, всё-таки, большой или небольшой?


    1. G1yyK Автор
      31.10.2018 08:41
      +1

      не тут как отрицание — большого комка грязи


      1. Dreyk
        31.10.2018 10:06

        тогда пробел нужен после «не»


      1. GennPen
        31.10.2018 10:15

        Тут у вас отрицание не отдельного слова(небольшой = маленький), а всей фразы. Поэтому правильно писать с пробелом.


      1. dedmagic
        31.10.2018 10:17

        Пробела не хватает.
        «Не большой кусок грязи». Чтобы программистам было понятнее: «не (большой кусок грязи (big ball of mud))». :-)


  1. Marwin
    31.10.2018 08:48
    +3

    Главное не переезжать на микросервисы с количеством людей меньше микросервисов… ну вот решили мы сделать новый проект на микросервисах… всё красиво развернули, докер, куча баз, свежее апи, все дела, штук 10 сервисов пока. А разработчиков: один фиг 1-2 на бэке+сайт, плюс мобильщик, который так же должен заниматься своей частью бэка, если ему что-то нужно для мобилы по апи. И в итоге 80% времени чувак с сайта и мобильщик бессмысленно тратят время на понимание что идёт не так во всех этих микросервисах, которые намутил единственно разбирающийся в этом девопс. Ибо раньше они просто вставляли один метод в контроллер и всё, а теперь там 5 перекрестных вызовов между микросервисами, чтобы собрать все данные.


    1. G1yyK Автор
      31.10.2018 08:59

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

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

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

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


      1. stratosmi
        31.10.2018 17:03
        +2

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


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

        Это не одно и то же, что и отличная спецификация (которая еще и постоянно меняется).

        Тут проблема совсем в другом.

        Ваш оппонент правильно сказал:

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

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

        И это не решается сколь угодно точной спецификацией. Хотя бы посмотрите на отладку? Все уже написано по спецификации. На этапе отладки спецификация вам уже не поможет.


        1. VolCh
          31.10.2018 17:48

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


          1. Losted
            31.10.2018 21:26
            +1

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


          1. creker
            31.10.2018 22:43

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


    1. RouR
      31.10.2018 09:25

      Добавьте трассировку (Zipkin, Jaeger)


  1. G1yyK Автор
    31.10.2018 10:25

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

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


  1. ikirin
    31.10.2018 10:45

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


    1. G1yyK Автор
      31.10.2018 10:57
      -1

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

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

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


      1. RPG18
        31.10.2018 11:41

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

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


        нужно перепрлачивать за серверное железо

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


        1. VolCh
          31.10.2018 17:56
          -3

          Монолит будет масштабировать дороже. Грубый пример: два модуля в монолите, каждый хочет по 8 Гб оперативы, работает на сервере на 16 Гб. Вдруг нагрузка на второй модуль увеличилась и решаем чтобы два инстанса его работали. Архитектура позволяет, масштабируемся на второй такой же сервер. Всё хорошо, но вот первый модуль теперь вхолостую жрёт 8 Гб, потому что он тоже отмасштабировался как часть монолита. А с микросервисами (точнее сервисами, необязательно микро) мы масштабируем только нужные модули. В нашем примере у нас сначала два сервера по 8 Гб, а потом 3 по 8Гб, а не сначала один на 16, а потом два на 16.


          1. RPG18
            31.10.2018 18:05
            +1

            Лично я пишу на C++/Go и когда модуль который ничего не делает, но жрет 8Гб, то для меня это звучит как бага.

            Вроде звучит как монолит на Java, но я видел монолиты на Java, которые не съедают все ресурсы сервера.


            1. VolCh
              31.10.2018 18:13

              Я же написал «грубый пример». Придраться тут можно много к чему, это просто демонстрация идеи. Замените 8 на X, а 16 на 2X. X возьмите приемлемый для своих реалий.


              1. RPG18
                31.10.2018 18:18
                -1

                Давайте будем реалистами. Ничто из ниоткуда не берется.


                1. VolCh
                  31.10.2018 18:21

                  А кто говорит про «ниоткуда»? Разбиение монолита на сервисную архитектуру не бесплатно и для разработчиков, и для эксплуатации.


                  1. RPG18
                    31.10.2018 18:43
                    +2

                    А кто говорит про «ниоткуда»?

                    Вы:


                    два модуля в монолите, каждый хочет по 8

                    Сервис ничего не делает, но уже съел память. Уход на X и 2X ничего не меняет. Может быть вы приведёте реальный пример, где такое потребление ресурсов, это не архитектурная ошибка.


                    1. VolCh
                      31.10.2018 23:37

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


                      1. RPG18
                        01.11.2018 14:22

                        Давайте приведу пример из жизни. PostgreSQL— это типичный монолит. Я могу запустить его на 1 core 512mb, так и на 64 core 512Gb. Все потому, что разработчики не стали харкодить параметры, а вынесли в конфиг. Соответственно, если вынести настройку компонентов в конфиг, то можно запускать только то, что нужно.


                        1. VolCh
                          01.11.2018 15:22

                          PostgreSQL — это типичный пример сервис-ориентированной архитектуры. Посмотрите сколько разных исполняемых бинарников в нём. Сколько разных процессов крутится.

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


                  1. bo0rsh201
                    31.10.2018 22:48

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


                    1. VolCh
                      31.10.2018 23:39

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


                    1. MikailBag
                      31.10.2018 23:47

                      А куча сетевых запросов с сериализацией/десериализацией ресурсы не тратит?


    1. tuxi
      31.10.2018 11:47

      золотые слова, присоединяюсь


    1. stratosmi
      31.10.2018 16:39

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


      Вы вполне можете запускать монолит в облаке.

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

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


  1. jaiprakash
    31.10.2018 11:04
    +1

    Ещё один аспект — микросервисы позволяют использовать GPL код совместно с вашим закрытым.


    1. G1yyK Автор
      31.10.2018 11:20
      -1

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

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


      1. ikirin
        31.10.2018 11:27

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

        Монолиты так же живут хорошо в облаках

        Я это и не опровергаю.

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

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

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

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


    1. ikirin
      31.10.2018 11:26

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

      Монолиты так же живут хорошо в облаках

      Я это и не опровергаю.

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

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

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

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


    1. vanxant
      31.10.2018 11:33
      +1

      Пока вы не распространяете свой закрытый код, вы можете монолитно (статически) линковать его с GPL кодом. Иначе нужно использовать динамическую линковку (dll), где все gpl модули вынесены в отдельные файлы dll.


      1. Free_ze
        31.10.2018 12:23

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


  1. Tiendil
    31.10.2018 13:05

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

    В одних случаях это хорошо, в других — плохо.


    1. VolCh
      31.10.2018 18:05
      +1

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


      1. Tiendil
        31.10.2018 18:45
        +2

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

        На уровне ифраструктуры это как раз перераспределение.


        1. stratosmi
          31.10.2018 19:22

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


          Если уже написан и отлажен — да.
          А ошибки сети, а балансировка? Как это все отлаживается — неужели нет разницы?


          1. Tiendil
            31.10.2018 19:36

            Балансировка — это инфраструктура. Обработка ошибок сети реализуется один раз (или один раз на каждый ЯП).


            1. stratosmi
              31.10.2018 20:10

              Обработка ошибок сети реализуется один раз


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

              Вы как-то слишком упрощаете.

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

              Но в таком случае вы теряете много контроля над процессом.


              1. Tiendil
                01.11.2018 09:57

                >если логика задачи требует повторных попыток?
                То они были бы и без микросервиса.

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

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


                1. stratosmi
                  01.11.2018 11:22

                  То они были бы и без микросервиса.


                  Внутренние вызовы не в пример надежнее, чем внешние RPC.


                  1. Tiendil
                    01.11.2018 12:00
                    -1

                    >Внутренние вызовы не в пример надежнее, чем внешние RPC.
                    Но это не значит, что их ошибки можно не обрабатывать. Всё равно надо. Какая разница, как часто фейлится логика: 1 из 1000, или 1 из 1000000. На больших числах ошибки всё равно будут.

                    Внутренние это на одном железе которые?

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

                    Вот микросервисы, кстати, ещё можно так разворачивать — код + небольшая база (и то спорный вопрос).


                    1. VolCh
                      01.11.2018 12:19

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


                      1. Tiendil
                        01.11.2018 13:00

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

                        Я думаю, большинство людей всё-таки имеет в виду более широкую трактовку.


                        1. VolCh
                          01.11.2018 13:18
                          +1

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


                1. stratosmi
                  01.11.2018 11:24

                  Достаточно одного раза, в чём проблема?


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

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


                  1. Tiendil
                    01.11.2018 11:55
                    -1

                    Код инициалиазции, переподключения, обработки ошибок содинения пишется один раз.

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

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


                1. andreyverbin
                  01.11.2018 12:58

                  если логика задачи требует повторных попыток?
                  То они были бы и без микросервиса.

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


            1. 0xd34df00d
              31.10.2018 20:20

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

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


              1. Tiendil
                01.11.2018 10:02

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

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

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

                И само собой, микросервис — не серебрянная пуля. Если он реально мешает в каком-то частном случае, то не надо этот микросервис выделять.


        1. VolCh
          31.10.2018 23:43

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


  1. Ogoun
    31.10.2018 14:32

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

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

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


    1. stratosmi
      31.10.2018 18:36
      +1

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


      Blue-green deployment это называется.
      С монолитами вы тоже можете это делать. Точно так же.


    1. Stas911
      31.10.2018 22:41

      Постойте, а как же resume-driven architecture?


      1. Ogoun
        01.11.2018 14:49

        Как она строится?


        1. VolCh
          01.11.2018 15:23

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


  1. SUA
    31.10.2018 15:04

    Микросервисы это хорошо… когда они «микро» и реально изолированы друг от друга

    когда же методу требуется

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

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


  1. alatushkin
    31.10.2018 17:55
    +2

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


  1. bo0rsh201
    31.10.2018 19:50

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


    1. stratosmi
      31.10.2018 20:14

      Единственный вменяемый аргумент это возможность проще скейлится и делать это динамически + нет привязки к одному стеку company wide.


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

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


      1. bo0rsh201
        31.10.2018 20:39

        Полностью согласен. Это вопрос масштаба исключительно


      1. Archon
        31.10.2018 23:06

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


  1. funca
    31.10.2018 22:04

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


    1. Bonart
      01.11.2018 11:55

      Для «поделить работу» микросервисы не нужны. Совсем.


      1. VolCh
        01.11.2018 11:56

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


  1. Antigluk
    31.10.2018 22:08

    Самая большая боль, как по мне, так это развертывание всей этой карусели на локальной тачке. Допустим, часть сервисов крутится на стейджинге, а для разработки нужно поднять только часть из них: и начинается переписывание конфигов каждого из сервисов, чтоб они смотрели друг на друга.
    Это занимает много времени и порождает желание написать свои костыли в виде каких-то генераторов конфигов.
    Вот как вы живете с этим? Может есть таблетка от этого?


    1. biseptol
      01.11.2018 00:11

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


    1. creker
      01.11.2018 00:47

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


      1. stratosmi
        01.11.2018 09:10

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


        В логике бизнес-задачи это может быть изначальным.

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

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

        Ибо зачем вы остальные-то модуля писали вообще, если без них можно обойтись?

        Пример интернет-магазина habr.com/company/raiffeisenbank/blog/427953/#comment_19310299
        Не так уж много частей не задействовано, если мы проверяем ключевую операцию для такого проекта — как протекает оформление товара в целом.


      1. VolCh
        01.11.2018 09:35

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


    1. Kirhgoff
      01.11.2018 01:02

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


    1. VolCh
      01.11.2018 09:38

      Когда нужен только один сервис локально, а остальные со стейджинга идут, то нормально разруливается с локальным .env файлом в корне сервиса для докера. Или сервисов немного или они легкие, то и просто запустить всё локально приемлемо.


  1. funca
    31.10.2018 22:15
    +1

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


  1. unbelieving
    01.11.2018 04:18

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


    1. stratosmi
      01.11.2018 09:13

      В монолите все это делается один раз, в микросервисе десятки, а то и сотни раз за цикл обработки одного запроса.


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

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

      Чем получить систему более эффективно использующую железо, но позже.


      1. unbelieving
        01.11.2018 10:04

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


        1. stratosmi
          01.11.2018 11:27
          -1

          Итог — той компании нынче не существует. А жаль и идеи хорошие были и коллектив сильный


          Если компании по итогу не существует именно из-за технической ошибки, то коллектив там был сильный?


    1. VolCh
      01.11.2018 09:51

      Это предсказуемые, даже очевидные минусы.


      1. unbelieving
        01.11.2018 10:17

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


        1. VolCh
          01.11.2018 11:41

          Википедия:


          Архитектура постоянно подвергается критике с самого момента её формирования, среди новых проблем, которые возникают при её внедрении отмечаются:

          сетевые задержки[5]: если в модулях, выполняющих несколько функций, взаимодействие локально, то микросервисная архитектура накладывает требование атомизации модулей и взаимодействия их по сети;

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


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