До микросервисов нужно дорасти, а не начинать с них

Original author: Nick Janetakis
  • Translation


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

У нас, разработчиков программного обеспечения, довольно интересная профессия. Мы можем спокойно кодировать целыми днями, а затем прочитать статью о чём-то — и она подвергает сомнению всю нашу работу, потому что какой-нибудь 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-приложением — платформой для размещения пользовательских курсов. Прямо сейчас над проектом работаю я один, и вы можете быть уверены, что я просто открыл редактор и начал писать код в первый же день.

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

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

Similar posts

Ads
AdBlock has stolen the banner, but banners are not teeth — they will be back

More

Comments 237

  • UFO just landed and posted this here
      +4
      Вы прочитали 1 книгу и делаете выводы. Есть очевидные места где надо делить. Просто не надо впадать в крайности.
      • UFO just landed and posted this here
          –1
          Ну вот например, пользователь загружает видео файл. Его нужно сконвертировать в другой формат, другое разрешение. Тут очевидно, что эту задачу нужно выделить в отдельный сервис.
            0
            Или, аналогично. Пользователь загружает 3D модель, для неё нужно срендерить превьюшки. Ну не будете же вы это делать в томже приложении?
              –1
              Очевидно что это нужно сделать сразу. Иначе у вас не будет возможности дорасти, потому что у вас вашего приложения не будет пользователей.
                +1

                Почему нет?

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

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

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

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

                          0
                          Зачем добавляшь еще один веб-сервер, если один и так справляется? А если не будет спраляться веб-сервер, зачем добавлять еще 1 рендерер?
                            0
                            Это немного отклонение от темы, но рендеринг 3D моделей обычно происходит на GPU, а сервер с GPU на порядок дороже сервера без него. Получается, если вдруг веб-сервер будет неспраляться с кол-вом запросов, вы добавите еще 1 сервер с GPU просто потому что это логичнее?
                              0
                              Вот это хороший ответ на «почему нет?» выше.
                0
                Почему это очевидно? Это прекрасно может работать в рамках монолита.
                  –1
                  Пользователь загрузил 20-и минутный видео файл в качестве 1024p. Его нужно предобразовать в видео меньшего разрешения: 720p, 480p и 360p. Какой алгоритм будет в монолитном приложении?
                    +2
                    Пользователь загрузил 20-и минутный видео файл в качестве 1024p. Его нужно предобразовать в видео меньшего разрешения: 720p, 480p и 360p. Какой алгоритм будет в монолитном приложении?


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

                    Как бы сделал я:

                    0) Балансировщик на входе — fabio/Traefik/nginx.

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

                    Это что для монолита, что для микросервисов нужно.

                    1) БД для метаданных видеофайлов, профилей пользователей, сессий, комментариев.

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

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

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

                    Все экземпляры всех видов СУБД — разумеется реплицируются.
                    Выделение Tarantool/Mongo/PostgreSQL позволит сделать удобную репликацию master-master для Tarantool/Mongo (Тарантул точно умеет, Монго, надеюсь, не помню точно). Это снимет нагрузку с PostgreSQL, так как он заметно хуже работает на большом количестве экземпляров (а тем более по сети) и позволит обойтись для PostgreSQL более мягким master-slave.

                    Что для микросервисов, что для монолита — эти СУБД будут.

                    2) Бэкенд. Вполне себе монолит. Большой и единый.

                    3) Фронтенд.

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

                    4) Модуль конвертации. Маленькая узкоспециализированная утилита. Даже какой нибудь ffmpeg годится.

                    С небольшой специально написанной обвязкой, например, подписанной на очередь и запускающий ffmpeg.

                    Или вообще без обвязки специальной — тот же Nomad из Hashicorp вполне годится, имхо. Его же можно для deploy новых версий бекенда использовать. Его же можно использовать для запуска ffmpeg

                    Что для монолита, что для микросервисов — все тот же ffmpeg и все та же обвязка.

                    5) Сервер очередей. Для более гибкого управления множеством инстансов.

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

                    Это нужно и для монолита и для микросервисной архитектуры.

                    6) cloud storage работающее по протоколу S3 или OpenStack Swift

                    Это нужно и для монолита и для микросервисной архитектуры.

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

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

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

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

                    Опционально добавляем:

                    8) Если бюджет позволяет более серьезно относится к диагностике — централизация сбора логов и метрик. Логи нужны всем. Метрики микросервисам важнее.

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

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

                    Итого имеем балансировщик, СУБД и MQ-сервер и cloud storage и кэш — обязательные как для монолитной так и для микросервисной архитектуры.

                    Варианты с монолитом:
                    1) Монолит бэкенда + конвертер.
                    2) Монолит бэкенда + конвертер + модуль upload

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

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

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

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

                      –1
                      Я один не считаю такое приложение монолитом? Для меня это SOA.

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


                          Не обязательно.

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

                          Если позволяет выбранная технология — будет у вас один инстанс обрабатывать и 10 000 потоков. Не позволяет — просто будете запуском дополнительных инстансов этот недостаток компенсировать.

                          И причина, по которой вы запускаете дополнительные инстансы — не важна.

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

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

                          Это важно и для монолита и для микросервисной архитектуры.

                          Давайте рассмотрим чистый монолит (сам конвертирующий видео файлы, сам же обрабатывающий запросы от пользователей) на примере ситуации, описанной ppl2scripts в habr.com/post/427215/#comment_19272331
                          Потому что завтра нужно будет отрендерить миллион превьюшек. Хорошо 50 тысяч. Тысячу.


                          Ситуация с монолитом не отличается от ситуации с микросервисами.

                          Определимся с вашей политикой использования вычислительных ресурсов. Что для монолита, что для микросервисов это будет одно и то же:
                          1. Или по мере освобождения вычислительных ресурсов, выделенных только под длительные операции. Таким образом, под трудоемкие операции выполняются только на определенном выделенном пуле вычислительных ресурсов.
                          2. Или по мере освобождения вычислительных ресурсов от других операций. В этом случае, фактически размер доступного пула динамически меняется в зависимости от нагруженности по прочим операциям
                          3. Или автомасштабированием — добавлением вычислительных мощностей, выполнением операции, освобождением вычислительных мощностей.
                          4. Или комбинацией этим методов.


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

                          1. В схеме бэкендом+конвертер мы просто запустим конвертер 50 000 раз.
                          2. Для бэкендов ничего не изменится.
                          3. В схеме с единым бэкендом — мы начинаем конвертацию, тем самым количество бэкендов, доступных для обычных запросов пользователей, сокращается. При обработке очередного запроса от пользователя обнаруживается, что обрабатывать запрос некому, так как свободных бэкендов нет. Просто запустим новый бэкенд. Очевидно, что при сохранении нагрузки придется запустить под быстрые запросы 50 000 дополнительных бэкендов, взамен тех, что длительное время будут заняты конвертацией. Если ваши бэкенды долго инициализируются это имеет смысл сделать заранее, одновременно с запуском конвертации. Или предусмотреть пул «горячих» свободных бэкендов
                          4. Рассмотрим ситуацию, когда конвертировать вообще ничего не надо. Но обычные быстрые запросы не успеваем обрабатывать. Просто запустим новый бэкенд. Ничем не отличается от предыдущего пункта в плане автомасштабирования. Только то было «автомасштабирование по причине того, что бэкенды заняты конвертацией». А это «автомасштабирование, так как бэкенды не успевают обработать обычные быстрые запросы». Но не отличается ровно ничем — ответ на недостаток ресурсов для обработки это запуск нового бэкенда


                          Но почему это произошло?

                          Если у меня год подряд было 1 000 в день, то вероятность того, что завтра будет 50 000 в день — крайне незначительна. А вероятность того, что будет миллион = 0.

                          Если такое случится, видимо, теперь мы мега-популярны и мега-посещаемы?

                          Так что следующий этап:

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

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

                          Платить за это заранее готов далеко не каждый.
                          А вдруг не будет не то что миллиона, а и 50 000 не будет никогда?
                          Сделать сразу «как у Фейсбука и Гугл» — это ж разница совсем не в 20% по стоимости работ. И по срокам тоже дольше.

                          А скорее всего для начала сгодится компромиссный вариант, описанный тут habr.com/post/427215/#comment_19276749

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

                          Вот пример примитивнейшей ситуации:
                          habr.com/post/282299
                          «Кэш внутри приложения» vs «Кэш рядом, в соседнем отдельном процессе».
                          А ведь в микросервисах, все еще хуже. Там и сетевые задержки. И переходов между процессами/модулями/сервисами куда как больше. И дополнительных сериализаций/десериализаций полным-полно. И пр.

                          Надо смотреть по конкретной задаче.

                          Ну вот пример очень даже посещаемого проекта:
                          habr.com/company/oleg-bunin/blog/418235
                          Как было раньше (со старта Авито до 2015 – 2016 годов): мы жили в условиях монолита, с монолитными базами и монолитными приложениями. В определенный момент эти условия стали мешать нам расти. С одной стороны, мы уперлись в производительность сервера с главной базой, но это не основная причина, так как вопрос производительности можно решить, например с помощью шардирования.


                          Как они пишут производительность можно было решить и с монолитом. А ведь это один из самых посещаемых сайтов в РФ, входит в первую десятку rg.ru/2017/09/28/nazvany-samye-populiarnye-sajty-v-rossii.html

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

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

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

                          Надо смотреть по конкретной задаче.
                            0
                            Я один не считаю такое приложение монолитом? Для меня это SOA

                            Зачем замыкаться в формальных определениях. Ведь чистых монолитов и не бывает.

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

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

                    Из опыта
                  +2
                  Да люди как люди. Кто-то начитался умных книжек и статей, кто-то просто хочет быть в тренде, кому-то банально скучно и хочется попробовать что-то новое. Что еще печальнее, часто им совершенно пофиг на судьбу проекта, зато потом в резюме можно написать «знаю стек netflix».
                    +1
                    Также можно сказать про ООП, ФП и другие подходы. А может просто кто-то не хочет говнокодить?
                      +10

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

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

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

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

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

                        Как говнокод связан с микросервисами? Микросервисы — это про архитектуру. А как она реализована — это уже другой вопрос. Говнокод с равной вероятностью может быть как в монолите, так и в микросервисах.
                          –1
                          Если впихивать невпихуемое в 1 монолитное приложение, то код приложения превратится в говнокод. Архитектура помогает этого избежать.
                            +3
                            А если бить на куски то, что должно работать вместе, то помимо говнокода, будет еще и ад с поддержкой этого чуда. Это я к тому, что как и вы, могу приводить крайние примеры. А нужно просто включать голову.
                              +4

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


                              Molonithic vs Microservices

                              image

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

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

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

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

                          Если же коммуникация между «сервисами» должна быть исключительно быстрой, лучше сделать монолит… У меня был опыт, когда в хорошем продукте всё равно пришлось несколько сервисов слить в монолит, потому как так работало лучше…
                          +1
                          смешно такое читать, достаточно посмотреть какой код пишут программисты без должного присмотра и сразу станет ясно почему микросервисы пихают вовсюда, с микросервисами не получаться макароны, вернее их создать сложнее, а в монолите легко, даже думать не надо, почему-то все забывают что главная проблема это именно программисты, мы не любим работать много и хорошо, а если ещё и менеджеры такие которым уяк-уяк и в продакшен то код в какашку быстро превращается, а микросервисы это физическое разделение кода и откуда попало не вызовешь любой кусок кода, многие ещё на ФП переходят там в некоторых языках вообще жёсткие ограничения, что сделать плохо сложнее чем сделать хорошо, но нужно понимать как оно должно быть иначе вообще ничего не напишется
                            +1
                            Отличный пример монолитного предложения, которое можно рефакторить в микропредложения
                              0
                              да! если написано хорошо то делается это всё легко и быстро
                            • UFO just landed and posted this here
                              +1
                              Никогда не говори никогда… ну и в целом не надо слишком сильно обобщать… Если разработчик привык фигачить микросервисы, то может быть вполне нормальной идеей писать сразу на микросервисах. Просто некоторые вещи сразу удобно выделять в микросервисы (например — КЛАДР классификатор, который по отдельности никому нафиг не нужен ни в одном проекте, но в целом компании нужно, чтобы все адреса задавались в едином формате), сервис отправки сообщений (sms, email, telegram) тоже никогда не влазит ни в один из сервисов компании, но оповещения клиентам может слать биллинг, система мониторинга сети или отдел маркетинга и все они хотят слать сообщения без заморочек и по тому каналу, который пользователь указал как приоритетный для связи… да тонны их. Ну а если непонятно «куда приткнуть эту фичу» или «она временная» или вообще «мы тут быстро на коленке накидаем, потом решим что с ним делать», то пусть будет один «микро» сервис, в котором, например, бизнес-логика и всё вот это вот непонятное… Как назвать получившуюся архитектуру с 1-2 кучами ака монолитами и обвязкой из нескольких микросервисов я не знаю, но обычно получается что-то подобное.
                                0
                                Это вы описываете не микросервисную архитектуру, а классическую сервисно-ориентированную (SOA). В которой критерием выделения сервиса является возможность его переиспользования или особые требования к автономности либо масштасштабируемости.

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

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

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

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

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

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

                                        Я заменяю in-memory database на чужую внешнюю бд, которая имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
                                        Я добавляю к приложению чужой внешний кэш, который имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
                                        Я добавляю к приложению чужой фулл-текст (эластик, к примеру), который имеет свой протокол обмена данных и может хоститься на отдельном сервере. Приложение перестало быть монолитом?
                                        Я добавляю к приложению балансировку нагрузки на одинаковые инстансы, которые не имеют возможности обмениваться данными, но могут хоститься на отдельном сервере. Приложение перестало быть монолитом?
                                        Я добавляю к приложению сервис авторизации, который выношу на отдельный сервер и который может обмениваться с основным приложением. Приложение перестало быть монолитом?
                                          +1
                                          Файлы вы храните в S3. Видео перекодируете в AWS ElasticTranscoder. RTMP транслируете через Red5. 3D модели рендерите SolidWorks. Email-ы рассылаете через SES. Картинки конвертируете ещё чем-то. И т.д.
                                          Да, на мой взгляд, это уже будет сложно назвать монолитным приложением.
                                            +2

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


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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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


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

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

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

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

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

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

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

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

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

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

                                                        еще раз, я не говорил про микросервисы, я имел в виду минисервисы.
                                                        Разница только в объеме кода или есть еще какая-то разница?
                                                      +4
                                                      Нет, это не правда. Размещение по серверам и монолитность никак не связаны. Можно сделать несколько копий монолита (воркеров) на слабых серверах за балансировщиком, а можно все микросервисы посадить рядом на один сервер.
                                                        –3
                                                        Сделать несколько копий монолита возможно только для очень простого монолита. Я даже таких приложений и не встречал.
                                                          +1
                                                          Почему вы так считаете?
                                                            0
                                                            Как-то глупо делать монолит(если он один) который будет складывать входящие запросы в базу, потом их оттуда забирает в правельном порядке. Но если их сатановится два, то это необходимо.
                                                            Что в таком случаи делать?
                                                            Либо делать оверхед одиночному монолиту, чтобы не переписывать когда их будет два? Или всё же переписывать когда надо будет?

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

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

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

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

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

                                                                  Вообще мне этот комментарий доставляет. Такое впечатление, будто вы думаете, что микросервис — это модуль, общающийся по сети.
                                                              –1
                                                              Я имел в виду что я не участвовал в разработке веб-приложения, которое можно было бы реализовать монолитным (UPDATE: правильнее сказать, целесообразно, потому что если сильно захотеть, можно в посмос улетель). Мне приходит в голову только онлайн-магазин, сайт на wordpress и что-то в этом роде. Более-менее сложное веб-приложение требует разделения на несколько независимых приложений.
                                                                –1
                                                                Еще меня удивляет реакция людей, которые минусуют. Такое ощущение, что здесь собрались люди, которые сложнее сайта на WordPress ничего не делали и такие комментарии:
                                                                Сделать несколько копий монолита возможно только для очень простого монолита. Я даже таких приложений и не встречал.

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

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

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

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


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


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

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

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

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

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

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

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


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

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

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

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

                                                            upd: Опоздал с сообщением, выше уже всё написали.
                                                              0
                                                              Всегда ли монолитное приложение можно разместить на 6 серверах?
                                                                +2
                                                                У вас просто монолита нормального не было. Вам никто не мешает строить монолит по нормальному, так чтобы можно было занять много серверов.
                                                                Личный опыт наблюдения за неправильными монолитами не значит, что большинство монолитов проектируются рукожопами.
                                                                  –1
                                                                  Т.е. вы утверждаете что любую задачу можно решить монолитным приложением, которое, в лёгкую, можно запустить на произвольном числе серверов? А если этого сделать нельзя, то приложение написано рукожопами?
                                                                    +2
                                                                    Т.е. вы утверждаете что любую задачу можно решить монолитным приложением
                                                                    Не-а, мы вообще не об этом говорим. Однако то, что монолит не всем приложениям подходит, вовсе не значит, что монолит нужно списывать в утиль.

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

                                                                                    И да, это был обычный монолит на десятках инстансов со временем эволюционировавший в SOA.

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

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

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

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

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

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

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

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

                                                                                    Потому что ваша система не умеет работать в нескольких инстансах.
                                                                                    Это не имеет отношения ни к микросервисам ни к монолитам.

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

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


                                                                                    Ну я бы решил сие с помощью MQ-сервера.
                                                                                    Это, имхо, довольно универсальный ответ на то, чтобы несколько инсансов приложения корректно совместно работали.
                                                                                    –1
                                                                                    Еще 1 пример, для nodejs. Чат на WebSocket'ах. Запустите его на 2 серверах :-)
                                                                                      +1
                                                                                      У того же редиса есть pub/sub, в нем и хранить состояние. Тогда экземпляров nodejs можно хоть десяток наплодить.
                                                                                        +1
                                                                                        Да, плохой пример.
                                                                                        0
                                                                                        В любом туториале по написанию чатов на вебсокетах объясняется как сделать несколько воркеров, общающихся друг с другом через мастер-процесс. Добавить еще один уровень в эту иерархию. тривиально.
                                                                                          0
                                                                                          В этом случае мастер и воркеры разные приложения. А спор в том, возможно ли это сделать 1 монолитным приложеним копии которго запущена на 2 серверах
                                                                                            0
                                                                                            Так чем же принципиально отличается взаимодействие двух приложений от взаимодействия двух серверов? В обоих случаях используется обмен сообщениями.
                                                                                              0
                                                                                              Ничем особо не отличается от синхронизации процессов после fork()
                                                                                          0
                                                                                          Ещё пример. Вам нужно сконвертировать видео загруженное пользователем. Вы будете его налету конвертировать монолитным приложением?

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

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

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

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

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


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

                                                                                                    0

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

                                                                                                      0
                                                                                                      Сервисов можно наплодить хоть сколько, при этом иметь 1 сервер для закачки файлов.
                                                                                                        +4
                                                                                                        А что мешает настроить балансировщик так, чтобы он определенные запросы отправлял строго на один конкретный инстанс?
                                                                                                        Во многом получится тоже самое, но без модульности.

                                                                                                        Но ваши примеры становятся все лучше и лучше
                                                                                                      0
                                                                                                      А что мешает на второй картинке вперед еще один балансер поставить?
                                                                                                        0
                                                                                                        Он там и подразумевается, только вот если балансировщик будет случайно выбирать сервер, то закачка будет начинаться каждый раз с 0 с вероятностью 1 / кол-во_серверов.
                                                                                                          0
                                                                                                          брр… как сложно. Тут проблема изначально с архитектурой наверное. каждый инстанс сервиса будет качать себе некий файл, несмотря на то, что его сосед уже это делал ранее?

                                                                                                          Все инстансы (реплики) могут ведь иметь общее файловое хранилище и работать с одними и теми же файлами.
                                                                                                            0
                                                                                                            На картинках я привел пример использования расширения для nginx (resumable_upload) которое работает с файловой системой. Т.е. в этом случае для него нужен сетевой диск. Сетевой диск — это отдельный геморрой. Сколько раз приходилось использовать, столькоже раз потом отказывться.
                                                                                                            0
                                                                                                            Есть такая штука как sticky session. И закачка в рамках одной сессии не будет иметь проблем
                                                                                          +3
                                                                                          монолитное приложение можно разместить только на 1 сервере

                                                                                          — не правда, кластеризация и балансировка запросов возможны и на монолите
                                                                                    0
                                                                                    Сравнение IO разных подсистем
                                                                                    Странно что никто до сих пор это не кинул
                                                                                    gist.github.com/jboner/2841832
                                                                                      0
                                                                                      Вы про это:
                                                                                      Send packet CA->Netherlands->CA 150,000,000 ns 150,000 us 150 ms


                                                                                      Между Калифорнией и Нидерландами 150ms. А точто такое же внутри одного датацентра?
                                                                                        0
                                                                                        Это если сервисы общаются peer-to-peer. Но люди хотят отказоустойчивости, горизонтальной масштабируемости и т.д. И тут приходят они, брокеры сообщений, и добавляют задержки.
                                                                                          0
                                                                                          Выше, товарищь приводил аргумент с сетевыми задержками как один из ключевых недостатков микросервисов перед монолитом. Другой товарищь приводит в подтвержение этого аргумента сетевую задержку между Калифорнией и Нидерландами. Ну очевидно что она будет большая. А какова эта задержка будет между серверами внутри одного датацентра? Пренебрежимо мала
                                                                                            0
                                                                                            А я говорю, что в современном мире мерить задержку, как передачу пакетов, неправильно.
                                                                                              0
                                                                                              Я видел приложение, которое гоняло между микросервисами файлы объемом 1-100 мегабайт в рамках одного API-запроса десяток раз. Даже на локальной машине это жутко тупило. Но это эпик случай.

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

                                                                                              Это вовсе не пренебрежимо малая задержка.
                                                                                            +1
                                                                                            Round trip within same datacenter = 0.5ms
                                                                                            А если учитывать tcp handshake, кучу промежуточных роутеров, фаерволов, несколько уровней балансировщиков, можно получить скорость, которую совсем не ожидаешь, особенно если микросервис однопоточный, не имеет очередь. Тут же всплывают вещи о которых надо думать, потери пакетов в сети, лимиты на процесс (которых можно не достичь при локальных сервисах) и прочее-прочее. И в итоге может оказаться, что сравнивая производительность проекта построенного на микросервисной архетикруте и монолита, разница получается не в пользу микросервисов, при большей суммарной производительности серверов где работают микросервисы.
                                                                                              0
                                                                                              tcp handshake: не обязательно создавать TCP подлючение на каждый запрос.
                                                                                              кучу промежуточных роутеров, фаерволов: например в AWS/Azure есть опция (Accelerated Networking) которая отрубает фаервол.
                                                                                                +1
                                                                                                А я и не спорю, если вы заметили
                                                                                                Я привел сравнительную таблицу только для одной цели, оценить задержки разных подсистем. Разбивая монолит на микросервисы вы добавляете значительную сетевую работу, которая медленнее всего, даже если это 10G. Приведение форматов обмена между микросервисами тоже необходим, а протокол общения добавляет кол-во возможных исключений. Что делать при отсутствии сети, потере пакетов, недоступности какого-либо сервиса, ошибок ответа, перегрузке вм-ки где работает сервис. И это только сетевая часть. А если немного поофтопить, и коснуться деплоя, то возникают вопросы версионности, внедрение фич касающийся сразу нескольких сервисов, обратной совместимости (при rollback и смене версий), сложности CI/CD, балансировке, сервис-дискавери. Повторюсь, я не спорю, просто разбивая на микросевисы, вы выносите изнутри наружу всю сложность связности. Когда то это оправданно, но чаще нет.
                                                                                        +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 %'

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

                                                                                                                Пример посложнее: транзакция оплаты товара пользователем через внешнюю платежную систему. Статус заказа должен изменяться на «оплачен» только если оплата прошла, причём ответ платежной системы может быть «прошла» или «не прошла», синхронным или асинхронным, а может вообще ответ не дойти и надо самим постучаться на сервер и проверить.
                                                                                                    0
                                                                                                    А ты где-то видел схему с «делай обратную операцию» работающую реально? Я вот как-то не верю что ее можно руками сделать вообще надёжно, даже для простых случаев.
                                                                                                    Да даже если так сделать — все равно ж это не 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
                                                                                                      Как вытащить всех пользователей с age=23 из городов с country='RU'?

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


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


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

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


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

                                                                                                    0
                                                                                                    Например что если данные лежат в двух отдельных БД — невозможно гарантировать их консистентность.
                                                                                                    Почитайте, удивитесь: habr.com/company/oleg-bunin/blog/418235
                                                                                                      0
                                                                                                      Эта статья как раз отличная иллюстрация моего поинта. Чтобы обеспечить хоть какую-то целостность данных и транзакционность в распределенной системе — там ужас что пришлось городить. При этом этот их алгоритм все равно не гарантирует ни целостность, ни транзакционность — он лишь обеспечивает какой-то приемлимый уровень.

                                                                                                      А еще в статье явно написано что они уперлись в производительность монолита. Т.е. до этого они монолите построили крупнейший в россии интернет-магазин.
                                                                                                        0
                                                                                                        А еще в статье явно написано что они уперлись в производительность монолита. Т.е. до этого они монолите построили крупнейший в россии интернет-магазин.


                                                                                                        Там не так написано.

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


                                                                                                        Они уперлись в производительность монолита.
                                                                                                        Но видели пути решения.

                                                                                                        Однако, заодно им захотелось все переписать, ибо им было неудобно.
                                                                                                          0
                                                                                                          Ну да, не видели пути решения, и решили все переписать. Большинство статей про микросервисы так начинается.

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


                                                                                                      Если вы будете масштабировать монолиты горизонтально (количеством)
                                                                                                      или добиваться отказоустойчивости монолитов (количеством же)
                                                                                                      то эти проблемы к ним тоже отнесутся.
                                                                                                    –12
                                                                                                    У нас в группе обслуживающей одного из крупнейших продавца товаров общего потребления недавно попытались внедрить сетевой сервис, с опцией, что если повезёт и «все будет легко и просто» внедрить сервис на базе микросервис архитектуры 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-е кратной суммой, поскольку в пересчете на потерянное время от удовольствия от алкоголя с вожделенной закуской, препирательства были неуместны.

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

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

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

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

                                                                                                      Вы это хотели сказать? Тогда вы не правы.
                                                                                                      Любая технология применима в одних ситуациях и неприменима в других. Вообще любая.
                                                                                                        +2
                                                                                                        Какой то несвязанные поток предложений, вы не умеете формулировать мысли?
                                                                                                        И причём тут рыба?
                                                                                                        Причём тут IIS? Микросервис можно и на нём запустить, что именно девушка сделала не так? Докер тут вообще не причём, это всего лишь виртуальная машина.
                                                                                                          0
                                                                                                          Докер это все-таки технология контейнеризации, и сам по себе виртуальной машиной не является.
                                                                                                            –1
                                                                                                            По пунктам:
                                                                                                            1. Docker «это всего лишь виртуальная машина» — нет.
                                                                                                            2. «при чем она» — ответ чуть ниже.
                                                                                                            3. «Микросервис можно и» — нет, нельзя. Сервис, не изолированный от ОС является просто «сервисом». Другое дело, что определение не ограничивает средства изоляции контейнерами. Но то, что изоляция необходима определено совершенно четко.
                                                                                                            4. рыба это пример, компьютеры не нужны, если принять концепцию автора «надо как дешевле, главное чтобы работало» Без компьютеров дешевле, и прекрасно работает.
                                                                                                              0
                                                                                                              >>Сервис, не изолированный от ОС является просто «сервисом».
                                                                                                              Кто такую чушь сказал?
                                                                                                              Та штука, поднятая на IIS, точно такой же микросервис. И это всего лишь вопрос удобства развёртывания и безопасности, в докере он, или нет, или в какой-то виртуальной машине, или на выделенном кластере.
                                                                                                                –1
                                                                                                                Одно из двух, или все ПО microservice, включая то, что на тех самых «выделенных кластерах», или Вы не правы и хамите.

                                                                                                                То есть Вы не правы и хамите.
                                                                                                                0
                                                                                                                Микросервис или «просто» сервис определяется не изоляцией, а функциями сервиса. Микросервис выполняет только один типа задач. Никто не запрещает вам на один физический сервер без всяких средств контейнеризации или виртуализации задеплоить 5000 микросервисов. С другой стороны, если вы запуститет виртуалки, в них докер и там разместите просто сервисы или монолиты, приложени ене станет вдруг микросервисным.
                                                                                                            +6

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

                                                                                                              +1
                                                                                                              сервис на базе микросервис архитектуры Docker
                                                                                                              — с каких это пор Docker стал микросервисной архитектурой?
                                                                                                                0
                                                                                                                Реализация microservice Microsoft основана на архитектуре Docker. Вот «reference example»:

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

                                                                                                                На все остальные вопросы — Яндекс в помощь.
                                                                                                                  0
                                                                                                                  микросервисы и архитектура Docker — вообще никак не связанные между собой вещи. Даже по Вашей же ссылке написано:
                                                                                                                  This guide is an introduction to developing microservices-based applications and managing them using containers.
                                                                                                                +1
                                                                                                                Микросервисы иногда напрашиваются на старте — когда есть куски работы, слабо связанные по времени исполнения (имеется ввиду процессорное время) и результаты работы этих кусков допускают возможность краша. Сейчас работаю над проектом, в котором есть основной сервис со своей базой данных, и есть добытчик данных, которые основной сервис периодически запрашивает у добытчика. Оба сервиса, конечно, синхронизированы по времени обновления данных, но если у добытчика отказ, то основной процесс от этого не страдает — он работает на уже собранных данных — тут изначально напрашивалось разделение на сервисы, что и было реализовано в архитектуре. И здесь проявляются преимущества микросервисов — добытчики данных могут менять алгоритмы сбора данных как угодно без необходимости править весь проект — требуется лишь поддерживать стандарт интерфейса передачи данных между сервисами, можно балансировку и резервирование легко сделать для добычи данных — надо лишь на основном сервисе добавить адреса добытчиков. Сервисы в данном случае занимаются каждый своей работой.

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

                                                                                                                Статья же — однобокая, но она так и задумана, наверное. Ведь действительно лучше сделать работающее приложение, которое еще сто раз поменяется, чем стараться изначально все эти сто предстоящих изменений предусмотреть — и, конечно, все равно ошибиться, ибо всего не учтешь. Но то, что изначально хорошо можно вынести в отдельный сервис — почему бы и не вынести, если есть время и ясное понимание и обоснование преимуществ такого решения.
                                                                                                                • UFO just landed and posted this here
                                                                                                                    0
                                                                                                                    Микросервисы — это не идея, это архитектурное решение на основе этой идеи в условиях распределенных систем. Не надо тут астронавта изображать.
                                                                                                                    • UFO just landed and posted this here
                                                                                                                        0
                                                                                                                        Ну в целом да, любая nix система это набор отдельных программ, которые могут быть удалены-заменены без вреда для основной системы. Есть ядро (kernel), а остальное — внешние независимые друг от друга (в идеале конечно) программки.
                                                                                                                          0
                                                                                                                          Unix Way — это написать на Си отдельные программы и запускать их, пересылая текст через пайпы.
                                                                                                                          Микросервисы — общаться с другими серверами по сети, подключаемся по HTTP, пересылаем JSON, можем легко отмасштабировать горизонтально.

                                                                                                                          Идеи схожи, детали сильно различны, поэтому требуется отдельный термин (а есть еще S в SOLID, на ту же тему). Так-то ничего нового в мире, да и в литературе всего четыре сюжета.
                                                                                                                          • UFO just landed and posted this here
                                                                                                                              0
                                                                                                                              идеи философии un*x: разделить сложную задачу на простые задачи

                                                                                                                              Нет, нету такого в философии юникс. Она про то, как писать одну программу так, чтобы её могли потом использовать как угодно. Подход к проектированию снизу-вверх.
                                                                                                                              А вот микросервисы уже про разбиение, подход сверху-вниз.
                                                                                                                              • UFO just landed and posted this here
                                                                                                                                  0
                                                                                                                                  Можно ли киянку называть кувалдой?
                                                                                                                                  • UFO just landed and posted this here
                                                                                                                              +1
                                                                                                                              Вы немного путаете частное с общим. Микросерисы, написаные на JS тоже умеются общаться через сокеты/pipe по желанию и посылать данные не в json. Просто по HTTP+JSON так проще и поэтому многие так делают.
                                                                                                                            0
                                                                                                                            Статья, ссылка на которую вы дали — это ужасно. Автор не понимает, что он несет.

                                                                                                                            XML вместо сырого текста — это упрощение работы, а следовательно экономия времени и прочих ресурсов. Оптимизация расхода ресурсов — краеугольный камень любой экономики. Авторы вывода только потому получились такие складные, что он выкинул из расчетов экономику вообще. При этом он лицемерно писал на компьютере текст, хотя мог разослать всем нам по голубю.
                                                                                                                              0
                                                                                                                              Гм-гм, Джоэл вовсе не топит за использование сырого текста вместо XML. Перечитайте статью.
                                                                                                                                0
                                                                                                                                Там на столько абстрактный текст, что можно что угодно в нем прочитать. По моему сам автор решил собой продемонстрировать, что такое абстракция.
                                                                                                                                  0
                                                                                                                                  Я там вижу две темы:
                                                                                                                                  — Хейт неоправданной абстракции, т.е. когда абстракция начинает приносить больше проблем, чем решать.
                                                                                                                                  — Хейт маркетинга, который врет о том, что новые штуки кардинально изменят жизнь, тогда как на самом деле они проводят только локальное улучшение.

                                                                                                                                  А что видите вы?
                                                                                                                            0
                                                                                                                            Могу сказать, что монолиты тоже следуют этой же философии UN*X.
                                                                                                                            В каждом своде правил/советов по хорошему коду есть пункт типа «каждый фрагмент кода должен выполнять одну задачу», разумеется, делать это правильно.
                                                                                                                            • UFO just landed and posted this here
                                                                                                                                0
                                                                                                                                Хм, даже не знаю как корректно ответить на ваш вопрос.
                                                                                                                                Грамотно написанные монолиты следуют этой философии. Т.к. вообще в программирование есть принцип разделения ответсвенности в коде.
                                                                                                                                • UFO just landed and posted this here
                                                                                                                                    0
                                                                                                                                    Вопросы все сложнее и сложнее. Не очень понимаю вопрос. И точно не смогу ответить без четкого определения монолитной и микросервисной архитектуры.
                                                                                                                                      0
                                                                                                                                      Не получится.
                                                                                                                                      Монолит отличается от микросервисов в первую очередь тем, что в монолите нельзя отключить определенный кусок когда тебе вздумается. Только целиком.
                                                                                                                                      А микросервисами можно манипулировать — включил-выключил-поменял без остановки других частей.
                                                                                                                                        0
                                                                                                                                        И тут на сцене появляется Эрланг, позволяющий срезать подковы заменять куски хода прямо на ходу.
                                                                                                                                          0
                                                                                                                                          Не имел удовольствия прикоснуться к Эрлангу.
                                                                                                                                          Если все как вы говорите, то если в куске, который заменили, во время замены проблема возникнет типа «Global apocalypse panic» — она за собой только этот кусочек потянет или всю конструкцию?
                                                                                                                                            0
                                                                                                                                            А к ПХП прикасались? ))
                                                                                                                                              +1
                                                                                                                                              Прикасался. И как раз в нем можно одной буковкой запятой повалить вообще все. Это явление я бы и назвал «монолит», когда либо все либо ничего (ну в пределах адекватности трактовки слова «все», а то можно в нем копаться философски ради копания).