×

Станут ли микросервисы архитектурой будущего

Меня зовут Михаил Бродский, я Lead Software Engineer, Consultant в GlobalLogic (Харьков). В сфере IT уже более 7 лет. Занимался проектированием, разработкой информационных систем и их внедрением. Сейчас возглавляю проект, связанный с сетевой безопасностью. Занимаюсь повышением эффективности процесса разработки с помощью виртуализации, разработкой и анализом архитектурных решений, а также реализацией программной функциональности.

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

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

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

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

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

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

Высокоуровневая схема микросервисной архитектуры

Почему мы использовали именно микросервисы?

В первую очередь из-за повышения скорости работы модели. При разделении монолитной системы на независимые элементы такую систему становится легче разрабатывать, ее можно «расскейлить», распараллелить: несколько команд смогут работать над разными микросервисами, при этом каждый микросервис будет иметь свой pipeline, continuous integration, continuous delivery. Таким образом, скорость работы системы повышается.

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

Это же относится и к работе с микросервисами: мы можем применять некоторые паттерны стабильности. Например, паттерн Timeout: если один из микросервисов не отвечает, мы можем быстро отключиться по тайм-ауту, показав пользователю, что этот сервис недоступен. Можно также применить паттерн Circuit Breaker («Предохранитель») — здесь уместна аналогия с домашней сетью электроприборов: при резком скачке напряжения барьер, контролирующий сетевое напряжение, отключает систему на некоторое время и после тайм-аута проверяет, вернулось ли напряжение в норму, можем ли мы подключить устройства к сети. Если нет, после определенного периода покоя проверка выполняется снова. Также возможно применение паттерна переборок. При распределении монолита между несколькими микросервисами становится возможным независимое применение таких паттернов.

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

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

Три основные группы микросервисов

Существует три основные группы микросервисов:

  • Stateless — сервисы без сохранения состояния.
  • Persistence — сервисы, которые сохраняют свое состояние.
  • Aggregators — агрегаторы.

Stateless

Такие микросервисы не имеют никакой зависимости от storage (cache и прочее) и определяют очень простые действия. Пример — конвертация из одной валюты в другую. Очень быстрое действие, нет зависимости от других сервисов и от дискового пространства. Их легко заменить и легко масштабировать.

Persistence

Другой тип микросервисов — сохраняющие свое состояние. К ним относятся сервисы, которые сохраняют зависимость от storage, у них есть операции записи/чтения, их точно так же легко масштабировать, если есть зависимость от диска, если разделены операции, применив паттерн CQRS. В двух словах: у нас есть запрос на чтение и запрос на запись. Мы можем распределить эти модели — за каждую модель будет отвечать определенный микросервис. Таким образом, мы можем масштабировать такую модель на независимые микросервисы. В первую очередь при этом мы зависим от других сервисов. Если взять Amazon или Netflix, один сервис вызывает огромное количество других сервисов. Кроме зависимости от других сервисов, есть зависимость от сети. Появляется запись в базу данных и, конечно же, Disk I/O Dependence.

Aggregators

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

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

Изначально наша архитектура выглядела так:

Микросервис-агрегатор с блокирующим (синхронным) запросом

Было устройство — брандмауэр, использовался микросервис, ответственный за сбор телеметрии (Device Data Collector MS), микросервис, ответственный за обработку полученной информации (Device Data Processor), а также микросервис, ответственный за генерацию уведомлений (Alert Generator).

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

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

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

Все было отлично, пока не поменялись требования. Вместо 5000 устройств от нас потребовалось подключение 50 000. И тут мы поняли, что возникнут проблемы. Собрали все метрики, проанализировали информацию — проблема заключалась в том, что устройство блокировалось на время обработки всей цепочки сообщения. Как можно было решить эту проблему?

Микросервис-агрегатор с асинхронным ответом

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

И тут возникает несколько вопросов.

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

  • Заблокировать отправителя до того момента, пока не будет обработано сообщение.
  • Блокировать очередь либо при увеличении сохранять ее часть на жесткий диск.
  • Применить метод контролирования обратного потока (используется в TCP-протоколе): создается буфер складирования сообщений, при переполнении которого поступление сообщений блокируется.

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

Третий. Что произойдет, если Device Data Processor не сможет выбирать сообщения (как мы описывали ранее)? А что, если устройству будет необходим результат обработки сообщения?

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

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

Системы обработки сообщений

Рассмотрим основные понятия.

Message

Первое — сообщение. Можно провести аналогию: HTTP-запрос.

Message Broker & Message Queue

«Посредники» — брокер сообщений или очередь. К ним относятся TIBCO Enterprise Message Service, WebSphere, webMethods, RabbitMQ, ActiveMQ, HornetQ, NATS, Apache Kafka. Это нечто среднее между RPS и реляционной базой данных. Другими словами, это базы данных, адаптированные исключительно для работы с очередью.
Приведу несколько различий между этими двумя подходами.

Direct Communication

TCP, one-to-one

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

UDP, ZeroMQ (over TCP), Webhooks (HTTP Callbacks)

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

Message Brokers

JMS, AMQP, RabbitMQ, ActiveMQ, HornetQ, Qpid, TIBCO Enterprise Message Service, IBM MQ, Azure Service Bus, Google Cloud Pub/Sub, SQS — их особенность в том, что при необходимости сообщить подписчику о нештатной ситуации (например, сообщение не было обработано, доставлено) используются посредники. Далее я расскажу, чем отличается Kafka от остальных существующих подходов.

Logs-Based Message Brokers

Посредники, работающие на основании логов.

HTTP Callbacks with Payload

Схема паттерна HTTP Callbacks with Payload

Этот метод объединяет посредника (Hub), подписчика (Subscriber), создающего сообщение, и издателя (Publisher). Например, подписчик заявляет, что хочет получать новости от определенного сервиса, и запрашивает ссылку на посредника (Hub): отправляет запрос, получает ссылку, отправляет подзапрос посреднику, происходит валидация подписчика. После этого, когда создаются дополнительные новости, посылается запрос на Hub о появлении новой информации, и посредник идентифицирует нового подписчика. Это стандартный паттерн — вы можете применить его, если нет необходимости использовать какого-то определенного посредника (например, Kafka).

Logs-Based Message Storage

Рассмотрим системы отправки сообщений на основании логов. К ним относятся Kafka, Distribute Logs от Twitter и реализация от Azure.

Схема работы систем сообщений на основе логов

У нас есть несколько очередей, несколько топиков, несколько разделов (Partitions). Есть продюсеры, которые создают сообщения и сохраняют их в очереди. Какую проблему решает этот подход?

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

Итак, у нас имеются очереди, добавляются продюсеры и потребители (Consumers). Когда какой-то из потребителей считывает сообщение, присваивается сдвиг (Offset): сколько сообщений было прочитано и какое сообщение было прочитано. Допустим, если мы прочитали определенное количество сообщений в разделе 0, мы записываем, чему равен сдвиг для этого раздела (например, 6):

Offset for P0 = 6

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

Объем релиза

В теории графов существует интересная формула, которая подсчитывает оптимальное число изменений в релизе: n — количество изменений (количество ребер в графе; соединения между ребрами — это изменения, зависимости) (рисунок 6). Политика Netflix — минимизировать число изменений, повысив частоту релизов. Если вы включаете в релиз большое число изменений, растет число дефектов, которые необходимо будет обнаружить и исправить. Например, при числе изменений n = 5 мы получаем 10 зависимостей. Минимизируя число изменений, мы уменьшаем число дефектов в системе.

Расчет оптимального релиз-скоупа

Выводы

В итоге на базе микросервисов мы создали асинхронный компонент, основная задача которого — сбор телеметрии от IoT-девайсов и создание необходимых оповещений (алертов) для уведомления пользователя. Каждые 2 часа мы получаем и сохраняем до 400 мегабайт информации.

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

  • получили практику предварительной оценки и разработки прототипов микросервисов;
  • с нуля создали асинхронный компонент, который позволил оптимизировать работу всей системы для большего количества подключенных устройств (до 50 000 устройств в одном регионе).
Что дальше? Мы смотрим в будущее с оптимизмом: переход от монолитной системы к микросервисам не только даст бизнесу и пользователям лучший user experience, но и позволит создавать целый набор различных сервисов, которые облегчат работу и жизнь.

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

Хотите узнать больше или есть вопросы? Пишите в комментарии, в LinkedIn и подписывайтесь на YouTube-канал.

Все про українське ІТ в телеграмі — підписуйтеся на канал DOU

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному3
LinkedIn

Схожі статті




75 коментарів

Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.

Жаль, что автор статьи так и не ответил ни один вопрос в комментариях

Я преобрел новым опыт работы с клиентской системой, получил предварительную практику разработки прототипов, с нуля создал...
Хотите узнать больше? Читайте на заборах страны.
#микросервисы #Netflix

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

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

*** его знает будет это будущее или нет. Надеюсь что нет.

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

Станут ли микросервисы архитектурой будущего

Ніт.

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

В нас, наприклад, схожа до вашої задача. Наш чудовий моноліт хендлить 10к рек-сек на віртуальному сервері за 5$.

Якщо у вас менше ~1кк активних юзерів/девайсів (а це більшість проектів) — то мікросервіси це гроші на вітер

Это зависит. Клиентов может быть относительно немного, но продукт может представлять собой что-то «очень data intensive» с большим массивом данных и достаточно нагруженным пайплайном их загрузки/обработки...

Так, звісно, що є виключення. Але якщо говорити про IoT, то там всюди одне й те ж.

Якщо у вас менше ~1кк активних юзерів/девайсів (а це більшість проектів) — то мікросервіси це гроші на вітер

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

Розбиваєте проект на модулі, і вуаля — кожен дев може комітит тіки в свій модуль.

Поясню на прикладі. В нас в проекті є пошук — знайти девайс по любому параметру. Можна зробити це мікросервісом — solr/elastic — але це купа оверхеду. Тому ми берем lucene, вбудовуємо в моноліт, виділяєм в окремий модуль.
Все, тепер всі задачі по пошуку ізольовані всередині одного модуля.
Коли настане час — і в нас буде 1кк девайсів і пошук стане проблемою — ми просто винесем його на окремий сервіс.

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

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

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

Этот подход не скейлит разработку как микросервисы(то что вы описали не есть микросервисным подходм не зависимо от того диплоете ли вы их отдельно, либо держите как компонент в отдельном репозе).
Этот подход не изолирует разработку бизнес(end-to-end) фич(основная идея микросервисов). Между командами.
У вас если elastic будет использоваться больше чем одним сервисом, то все команды будут сидеть и валить код в один и тот же компонент поиска, что бы релизить свои бизнесс фичи. Или одну бизнесс фичу будет делать больше чем одна команда отвечая по отдельности за компонент поиска, middleware еще что-то — что в любом случае хуже работать будет чем одна команда, которая может сделать midleware/поиск и задиплоить код, не выкатывая чужой код и не влияя на других — microservices.

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

Приклад, клієнт хоче не тільки пошук по девайсам, але і по юзерам.
Я створюю 3 таски: додати в індекс юзерів, додати в АПІ додатковий параметр «тип ентіті для пошуку», додати на UI пошук юзерів.
Всі 3 таски повністю ізольовані і не впливають одна на одну (крім точок дотику в search api, web api). Цю бізнес фічу 3 людини може робити паралельно. В чому проблема?

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

на каждый функционал у вас отдельная команда(скажем 60 человек в общем)

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

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

Ви постійно це повторюєте, але один з перших євангелістів мікросервісів — Нетфлікс і зробили вони це для скейлінга продукту, а не розробки.

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

Тут як в мікросервісі так і в моноліті декілька команд будуть змушені працювати над одним модулем/кодом. Створювати окрмий мікросервіс під 1 юз кейс це або самогубство, або ви — нетфлікс.

Мне мало интересны ваши оценочные суждения. Вы расскажите как мне решить проблему предложенную выше? или ваш подход с выделением компонента ее все-таки не решает — скейлинг девелопмента?

Вот как бы это выглядело с микросервисами ±
1. Device sevice
2. User/Admin service
3. Audit service
4. Relations/Connections service
В каждом работает отдельная команда — делают все начиная от апи заканчивая поиском, деливерят фичи по факту окончания разработки. Шарят вспомогательные данные данные через messaging(например users). Не тратят времени на планирование общего дизайна компонента поиска, что устроит 4 команды; быстрее проходят pull request review; не тратят на разговоры связанные с мерджем кода; упавшими тестами; не валят друг другу environment в связи с залитым неоптмизированным кодом; шарят меньше данных друг с другом и соотвественно меньше багами в данных блочат друг друга; не комитят друг другу в репозы ничего; выкатывают свою фичу, и сразу деливерят ее в прод если она рабочая по факту, а не ждут пока починит какая-то из команда баги в своем коде модуля с поиском. Это не netflix — это сейчас уже каждый 3-4 проект на любой крупной галере, где делают enterprise проекты. Если сомниваетесь — Зайдите на поиск и посмотрите сколько тут за последнее время было статей о внедрении safe от разных компаний.

Ви постійно це повторюєте, але один з перших євангелістів мікросервісів — Нетфлікс і зробили вони це для скейлінга продукту, а не розробки.

Вот выдержки из use-case netflix. Они решали все проблемы сразу geo-distribution, resilency и в том числе и скейлинг девелопмента —

Another distinct advantage of microservices is the speed and agility of development. Netflix engineers got the opportunity to develop, test, and deploy services independently, which allowed them to build more than 30 teams that could work on different parts of the system without having to wait for each other to finish. This helped the company develop faster and boost overall performance.

www.hys-enterprise.com/...​rn-from-their-experience

Наш чудовий моноліт хендлить 10к рек-сек на віртуальному сервері за 5$.

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

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

Для разворачивания монолита (т.е. всех сервисов) необходимо задплоить всего лишь одно приложение (war/ear) против 101-го микрсервиса. И для полноценной микросервисной инфраструктуры сейчас без docker и kubernetes (в большентсве случаев) не обойтись, что повышает требования к разработчикам.

Почему мы использовали именно микросервисы?
В первую очередь из-за повышения скорости работы модели. При разделении монолитной системы на независимые элементы такую систему становится легче разрабатывать, ее можно «расскейлить», распараллелить: несколько команд смогут работать над разными микросервисами, при этом каждый микросервис будет иметь свой pipeline, continuous integration, continuous delivery. Таким образом, скорость работы системы повышается.

Что такое скорость работы модели? Может быть скорость разработки? Но даже скорость разработки всей микросервисной системы будет ниже (значительно ниже на начальных этапах). И совсем не понятно, как pipeline, continuous integration, continuous delivery увеличивает скорость (как я понял производительность) работы системы?

Безопасность и стабильность... Например, паттерн Timeout: если один из микросервисов не отвечает, мы можем быстро отключиться по тайм-ауту, показав пользователю, что этот сервис недоступен. Можно также применить паттерн Circuit Breaker («Предохранитель») — здесь уместна аналогия с домашней сетью электроприборов: при резком скачке напряжения барьер, контролирующий сетевое напряжение, отключает систему на некоторое время и после тайм-аута проверяет, вернулось ли напряжение в норму, можем ли мы подключить устройства к сети ...

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

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

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

Станут ли микросервисы архитектурой будущего

Стала ли SOA из далеких 2000-ых архитектурой будущего? Нет конечно — она эволюцинировала в микросервисную. Думаю, такая же участь ждет и микросервисную архитектуру :) И да, сейчас она хороша для больших систем с большим числом команд разработки

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

На начальных этапах это когда? Когда в компании одна команда из 5 человек? Или когда у вас 100 человек работает над одним монолитом и из-за взаимозависимостей все фичи выкатываются одновременно раз в 3 месяца в лучшем случае?
Проблемы микросервисной архитектуры существует большое количество, но при определённых размерах команд и требованиях рынка они являются наиболее жизнеспособным решением, хотя конечно карту всех микросервисов перед сном лучше не смотреть :)

На начальных этапах это когда? Когда в компании одна команда из 5 человек?

Хороший пример, что быстрее будет, когда 5 человек должны запилить 10 сервисов для завершения MVP или 5 человек должны запилить 1..3 подсистемы?

Или когда у вас 100 человек работает над одним монолитом и из-за взаимозависимостей все фичи выкатываются одновременно раз в 3 месяца в лучшем случае?

Ну, я думаю, если в компании на начальном этапе 100 человек смогли удачно! реализовать и выкатить MVP релиз, пусть даже в течении пол года, то не имеет значение, какая там архитектура, эта команда сможет сделать все что вы захотите, хоть по нажатию вот той кнопки заварить вам кофе на Марсе :D

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

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

На начальных этапах это когда?

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

сейчас без docker и kubernetes (в большентсве случаев) не обойтись

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

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

Сотрудники ThomasCook (бывшие) с вами бы не согласились :).

У них не на скале было наверное, прост микросервисы.

Каждые 2 часа мы получаем и сохраняем до 400 мегабайт информации.

Итак tl;dr;

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

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

PS: Читайте в следующих выпусках.
* Весь наш зоопарк мы решили развернуть на высокопроизводительном кластере с использованием kubernetes. В итоге производительность поднялась до рекордных 250Мб в час.
* Частичный переход на cloud-based решения, чтобы привлечь дополнительных специалистов на проект.

Килобаксов? Скорее мегабаксов. Global Logic врядли бы брался за мелочь.

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

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

@wiki says:

UDP uses a simple connectionless communication model with a minimum of protocol mechanisms. UDP provides checksums for data integrity, and port numbers for addressing different functions at the source and destination of the datagram. It has no handshaking dialogues, and thus exposes the user’s program to any unreliability of the underlying network; there is no guarantee of delivery, ordering, or duplicate protection. If error-correction facilities are needed at the network interface level, an application may use Transmission Control Protocol (TCP) or Stream Control Transmission Protocol (SCTP) which are designed for this purpose.

Ну нет тут нихрена про необходимость передачи финансовой информации.

I know one UDP joke, but you might not get it.

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

А что, в асинхронном взаимодействии (через очереди) контракты не нужны?

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

Что есть контракт в RPC — endpoint + message structure. Контракт в messaging — queue/topic + message structure. Разница только в подходе по обработки сообщения, в RPC — синхронное, в messaging — ассинхронное. Из этого вытикает какие задачи имеет смысл решать в каждом из подходов. Пример проблемы, которая может возникнуть при асинхронном взаимодействии — есть сложный сценарий в котором взаимодействуют 5 микросеривисов. На продакшене иногда возникает проблемы в этом сценарии — то ли на уровне инфраструктуры, то ли есть где-то бага. Чтобы найти проблему вы в разы больше потратите времени в асинхронной архитектуре, чем в синхронной. А что там с точки зрения производительности? Я уже не говорю о сложности системы, тестировании и т.п. Так что утверждать, что messaging — это серебрянная пуля — совсем не корректно.

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

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

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

З.Ы. большенство ACID проблем прекрасно можно решить при помощи паттерна Saga

большенство ACID проблем

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

Я считаю (субъективно), что монолит хорош, когда он мал или средний.

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

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

Если под распределенной транзакцией подразумевается протокол 3-ех фазного коммита, то паттерн saga чуть-чуть о другом. И если ACID сильно критчно, то можно использовать паттерн расшаренной БД.

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

В большентсве монолитов логику можно разбить таким образом, что одну БД можно разделить на несколько. Но обычно народ, особенно в аутсорсинге, не замарачивается, и в итоге получаем Big ball of mud монолит.

расшаренной БД

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

В большентсве монолитов логику можно разбить таким образом, что одну БД можно разделить на несколько.

Ах лол ))))

и масштабированием

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

и масштабированием

Тут имелось в виду монолит vs микросеривсы (синхронные или асинхронные — все равно)

Если у вас сервис А синхронно дергает сервис Б, и вы масштабируете А — у вас же пропорционально растет нагрузка на Б, и вы вынуждены будете рано или поздно его скейлить тоже (а иначе вся система просто ляжет), не?

Не обязатально, хотя и возможно. Например, обротка запроса Client->A занимает 100мс и 1Мб, а обработка запроса A->B занимает 1мс и 1Кб.

И еще плюс синхронное взаимодействие между сервисами не ограничивает использовать non-blocking io в контексте одного сревиса

З.Ы. большенство ACID проблем прекрасно можно решить при помощи паттерна Saga

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

компенсирующие транзакции не могут падать...

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

Вот реальный пример, котрый народ самостоятельно реализовал — Оркестрируемая сага или как построить бизнес-транзакции в сервисах с паттерном database per service.

А вот ряд готовых решений на jvm:

Как и обычные ACID транзакции [могут падать — К.С.].

ACID означает определенный уровень гарантий — в том числе того, что упавшая транзакция оставит систему в консистентном состоянии, откатившись до ближайшего чекпоинта. В случае саги у вас сама суть в том, что падает одна из цепи локальных транзакций, и если не первая, то вся система в целом УЖЕ находится в неконсистентном состоянии, которое нужно откатывать другой цепью транзакций. Если при этом компенсирующую транзакцию(и) завершить не получается, означает это только одно — вы не смогли «вернуть все взад», и у вас система продолжает находится в неконсистетном состоянии. Это вот прямо совсем-совсем не то же самое, что упавшая транзакция в ACID, разве это не очевидно?

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

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

Это вот прямо совсем-совсем не то же самое, что упавшая транзакция в ACID, разве это не очевидно?

Конечно не одно и то же. Откат в ACID БД осуществляется средствами БД и он для клиента атамарен, а в компенсирующей транзакции/саги — средствами приложения и он совсем неатамарен. Поэтому и сложность реализации компенсирующих транзакций в разы больше, но и возможностей больше.

З.Ы. и если сильно критично использование ACID транзакций для ряда микросерисов, то всегда можно использовать паттерн Shared database. Ну а если для всех микросервисов будет юзаться одна БД, то надо очень серьезно задуматься в необходимости микросервисной архитектуры. Может быть достаточно будет нескольких монолитов? :)

надо очень серьезно задуматься в необходимости микросервисной архитектуры

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

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

Очень многое зависит от конкретных бизнес-сценариев. Например в микросервисной системе, состоящей из 500 сервисов у вас 5 сервисов используют одну БД для реализации каких-то критичных к ACID сцеариев. И после этого имеет смысл плюнуть на эту микросерисы и всем комнадам в общей сумме из 200 разработчиков дружно начать пилить монолит?

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

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

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

Приведи мне хотя бы пару побочных эффектов в синхронной микросервисной архитектуре, которые отсутсвуют в асинхронной.

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

Жесткая зависимость между микросервисами

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

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

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

усложнение отладки

Что ты подразумеваешь под отладкой? Локально поднять сервис и message брокер (например, TIBCO Enterprise Message Service) и ручками протестировать сервис? Так для этого необходимо писать функциональные тесты, а не заниматься мануальным тестированием — ты же разработчик, а не QA. Может возникают проблемы с инструментами при написании функциональных тестов? Решение очень простое даже под дотнетом (не говоря уже о jvm), первая строка в поиске гугла — WireMock.Net. Может быть проблемы в интеграционных тестах? Так их бессмысленно использовать без поднятия всех зависимостей. Или ты имеешь в виду remote debugging на продакшене, так тут я вообще не вижу разницы между синхронной/асинхронной архитектурой.

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

А вот по поводу монолита мне совсем не понятно ...

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

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

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

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

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

Там выходит жёсткая зависимость на уровне архитектуры, при чём здесь код?

А причем тут код к контракту микросервиса? С точки зрения архитектуры да, в RPC взаимодействии более жесткая связь, чем messaging. Но это не повод, где не попадя использовать асинхронную архитектуру. Вот представь .net приложение, в котором взаимодествие между компонентами токо на делегатах/эвентах (у меня был опыт поддержки такого гавна). Т.е. для вызова функционала из другого компонента дергаем делегат. Сложность системы выше — да, выше, но зато «гибко». Производительность ниже — да, ниже — вызов делегата дороже, чем вызов обычного метода, но зато «гибко». Вот такие же проблемы могут быть и в микросервисной архитектуре, построенной исключительно на messaging. Например, реализация обычного CRUDа для UI в разы усложнится.

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

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

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

А причем тут код к контракту микросервиса?

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

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

Я бы сказал, что не повод скорее называть свои распределённые монолиты и старую-добрую SOA микросервисами.

Вот представь .net приложение, в котором взаимодествие между компонентами токо на делегатах/эвентах (у меня был опыт поддержки такого гавна). Т.е. для вызова функционала из другого компонента дергаем делегат. Сложность системы выше — да, выше, но зато «гибко». Производительность ниже — да, ниже — вызов делегата дороже, чем вызов обычного метода, но зато «гибко».

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

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

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

Напомню, что микросервис должен иметь возможность деплоиться отдельно, работать отдельно (в общем случае не отправлять 500-ки и т.д., если другие не-инфраструктурные сервисы не работают), и является логической единицей (т.е., может состоять из нескольких сервисов внутри самого себя). Но все повально выкатывают продукты с диаграммой зависимостей, за которой не видно самих сервисов, потому что всё заштриховано в связях, и называют это микросервисной архитектурой. Как правильно ниже заметили, SOA уже 100 лет в обед. То, что там Сага прикручена, не делает её микросервисной — микросервисной её делает только самостоятельность отдельных сервисов (именно тогда они — микро), всё. А как самостоятельность без полного отвязывания друг от друга обеспечить? Никак.

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

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

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

В RPC на программном уровне никто не дергает друг-друга. Дергают в виде отправки сообщения по сети (TCP или HTTP). И проблемы с контрактом то же под вопросом — все зависит от технологий, которые вы используете. И мне не совсем понятно, почему вы считаете, что для messaging не надо особо заморачиваться с кнтрактом? Например, вам все равно, че там за типы сообщений гоняются: Command, Document, Event, Request-Reply. Особенно интересна ситуация с Request-Reply. Так что проблемы есть и при асинхронном взаимодействии.

Я бы сказал, что не повод скорее называть свои распределённые монолиты и старую-добрую SOA микросервисами.

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

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

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

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

Вот вам простой пример, есть необходимость реализовать отображение данных на UI. Данные управляются двумя серисами. Один юзает, например, MS SQL Server, другой графовую (Neo4j). Да, можно делегировать два запроса на UI (web, mobile Android и iOS), а можно реализовать отдельный сервис, который займется объединением этих данных. И вообще можно не юзать какой-либо монолит, а использовать, например, API Gateway основанный на GraphQL.

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

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

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

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

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

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

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

это абсолютно нормально — с этим совершенно согласен, но не стоит обобщать свой опыт на всю индустрию.

В RPC на программном уровне никто не дергает друг-друга. Дергают в виде отправки сообщения по сети (TCP или HTTP).

...через программный контракт.

И мне не совсем понятно, почему вы считаете, что для messaging не надо особо заморачиваться с кнтрактом?

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

Например, вам все равно, че там за типы сообщений гоняются: Command, Document, Event, Request-Reply. Особенно интересна ситуация с Request-Reply.

Конечно, всё равно — я без понятия, какие там требования и почему так). Идеальный вариант — log-style коммуникация. На .NET Fest’е в этом году, кстати, один из докладчиков описывал, как у них всё работает именно в такой концепции: Кафка используется по сути как база, из стримов данных идёт агрегация на лету, а готовые агрегации записываются в NoSQL базы отдельных сервисов в уже готовом виде, при этом если нужно что-то переделать/добавить/etc., то у них очень длинное окно хранения предыдущих сообщений.

Ну, я бы не сказал, что старая добрая SOA — это современная микросервисная архитектура.

Только описываете именно её).

Хотя по мне, так микросервисы — это эволюция SOA.

Так и есть.

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

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

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

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

Вот вам простой пример, есть необходимость реализовать отображение данных на UI. Данные управляются двумя серисами. Один юзает, например, MS SQL Server, другой графовую (Neo4j). Да, можно делегировать два запроса на UI (web, mobile Android и iOS), а можно реализовать отдельный сервис, который займется объединением этих данных. И вообще можно не юзать какой-либо монолит, а использовать, например, API Gateway основанный на GraphQL.

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

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

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

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

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

Например, мы распилил огрмный монолит на 3 самостоятельных сервиса — это и есть микросервисная архитектура?

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

Или следующее утверждение тоже будет верным — у нас есть микросервисная архитетура из одно самостоятельного сервиса?

Нит.

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

Если идти в логике, что давайте всё побьём на 100500 «типа микросервисов», лишь бы больше, но с похеренным контекстом, то да, получится фигня).

И сама архитектура не дает какого-либо ответа на этот вопрос.

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

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

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

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

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

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

Это больше похоже на отчет руководителю, полный воды и салата, лишь для того чтобы объяснить, почему мы сделали вундервафлю, сильно усложнив разработку и поддержку, для 170(!) запросов в секунду, и ДО 200мб в час(!) каких-то данных..
И почему микросервисы лучше монолита — так и не написали. Хоть бы метрики показали, как-то сравнили с цыфрами

для 170(!) запросов в секунду

Как только появляются скриптовые веб фреймверки то иной раз и 30-40 запросов в секунду уже хайлоад.

За попытку спасибо, но все же это не статья, а какой-то копипаст терминов из справочника.

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

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

По сути ваша статья не о микросервисах а о том, что есть такая хорошая вещь как Message-Driven и брокеры.

Вы подняли интересные вопросы о контроле и доступности, но не раскрыли их.

Так станут ли микросервисы архитектурой будущего?

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

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

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

Да

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

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

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

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

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

Підписатись на коментарі