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

Ваша система не доросла до необходимости использовать микросервисы
Ваша система не доросла до необходимости использовать микросервисы

Я не рассматриваю здесь другие доводы за микросервисы: упрощение доработок легаси и deploy fast (CI/CD). Об этом в другой статье.

И все же рассмотрим как распределенные архитектуры (и микросервисы в частности) помогают реализовать high load системы


Data-bounded шаблоны масштабирования — окончание

Чтобы не усложнять статью я не рассматриваю здесь остальные паттерны распределенной архитектуры, кроме микросервисов:

  • SOA (Service-Oriented Architecture, Сервисно-ориентированная архитектура), сервисы связаны напрямую или через ESB

  • SBA (Service-Based Architecture), сервисы обычно знают только о своих соседях и взаимодействуют напрямую, что делает архитектуру менее централизованной

  • Space-Based Architecture, единая БД, локальные синхронизируемые кеши чтения и записи либо in memory data grid

Они все основаны на единой БД и с точки зрения распределения данных одинаковы. Из-за отсутствия распределенности данных нет и проблемы их консистентности. Впрочем, кэширование записываемых данных уже приводит к Eventual Consistency.

Более полное описание можно найти в книге "Фундаментальный подход к программной архитектуре: паттерны, свойства, проверенные методы" Марк Ричардс и Нил Форд

Распределенные системы. Микросервисы

Для упрощения я ставлю знак равенства, что конечно же не так.

Заблуждения распределенных вычислений:

  • Сеть надежна;

  • Задержка равна нулю;

  • Пропускная способность бесконечна;

  • Сеть безопасна;

  • Топология не меняется;

  • Есть один администратор;

  • Стоимость транспортировки равна нулю;

  • Сеть однородна;

  • Сторона, с которой вы общаетесь, заслуживает доверия

  • Управление версиями — это просто

  • Компенсирующие обновления всегда работают

  • Наблюдаемость необязательна

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

Преимущества

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

  1. Радикальная изоляция данных.

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

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

  2. Гибкость разработки и развертывания. Мультитехнологичность

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

    • Изменения в одном сервисе не требуют перезапуска всей системы.

  3. Ускорение Time-to-Market. CI/CD

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

Частично эти свойства можно получить и при использовании монолита.

  • Вместо CI/CD будет blue-green deploy и часто этого достаточно. Также можно использовать плагин архитектуру для отключения компонента в виде dll, его замены и запуска. Прямые вызовы кода и единая БД при этом остаются.

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

Trade-offs

  1. Жертва консистентностью.

    • Данные между микросервисами синхронизируются через асинхронные сообщения или события, что приводит к eventual consistency и необходимости увязывания данных, например чрезе паттерн Сага (разбить общую логику на цепочку локальных транзакций, где каждая выполняется в одном сервисе, а в случае ошибки вызываются «компенсирующие транзакции» - отмена).

    • Это требует дополнительных усилий для обеспечения согласованности данных и обработки ошибок.

  2. Сложность взаимодействия.

    • Микросервисы требуют хорошо продуманной архитектуры взаимодействия (API Gateway, REST, gRPC и т. д.).

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

  3. Сложность инфраструктуры.

    • Для работы микросервисов нужна развитая инфраструктура: оркестрация контейнеров (Kubernetes), системы мониторинга (Prometheus, Grafana), централизованное логирование и трассировка (Jaeger, Elastic Stack).

    • Увеличивается нагрузка на DevOps-команду.

  4. Рост накладных расходов.

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

    • Трассировка и отладка распределенных систем становятся сложнее.

  5. Высокие требования к команде.

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

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

  • CQRS и Event Sourcing: Для разделения чтения и записи, а также хранения истории событий.

  • Кэширование: Для ускорения работы и снижения сетевой нагрузки.

  • Шардирование и репликация: Для масштабирования внутри микросервиса.

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

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

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


Вот краткое описание для каждого типа согласованности, включая 2–3 проблемы, последствия, а также примеры приложений и объяснение, почему эти проблемы не критичны для них.


Обновлённые последствия с примерами:


1. Strong Consistency (Сильная согласованность)

  • Проблемы:

    • Высокая задержка (latency).

    • Низкая доступность.

  • Последствия:

    • Долгие задержки при выполнении операций.

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

    • Временная недоступность системы при сбоях.

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


2. Eventual Consistency (Сходимость к согласованности)

  • Проблемы:

    • Временная несогласованность данных.

    • Конфликты данных.

  • Последствия:

    • Пользователи могут видеть устаревшие данные (от секунд до минут).

      • Пример: в социальной сети пользователь может не видеть новый комментарий к посту в течение 30 секунд. Лайк может отображаться с задержкой до 1 минуты.

    • Конфликты данных могут привести к потере или дублированию информации.

      • Пример: два пользователя могут одновременно изменить поле профиля в системе, и один из вариантов будет перезаписан (last write wins).

    • Некорректные результаты аналитических запросов.

      • Пример: в онлайн-магазине количество товара может отображаться как 10 единиц, хотя фактически их уже осталось 5.


3. Linearizability (Линейная согласованность)

  • Проблемы:

    • Высокая стоимость производительности.

    • Сложность реализации.

  • Последствия:

    • Увеличение задержек из-за необходимости глобальной синхронизации.

      • Пример: при записи данных в распределённую базу Google Spanner транзакция может занять до 200 мс из-за необходимости согласования между датацентрами.

    • Рост времени отклика в критических разделах системы.

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


4. Snapshot Isolation (Изоляция снимков)

  • Проблемы:

    • Фантомные чтения.

    • Высокое потребление ресурсов.

  • Последствия:

    • Фантомные записи могут привести к некорректным аналитическим данным.

      • Пример: аналитический запрос в базе данных может показать 100 заказов, хотя после начала транзакции добавилось ещё 5, и они не учитываются.

    • Рост потребления памяти для хранения снимков данных.

      • Пример: в PostgreSQL или Snowflake длительная транзакция увеличивает объём временных данных, что может замедлить выполнение других запросов.

    • Ошибки при выборке данных.

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


5. Causal Consistency (Каузальная согласованность)

  • Проблемы:

    • Сложность отслеживания зависимостей.

    • Увеличение объёма метаданных.

  • Последствия:

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

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

    • Некорректное отображение изменений в системах совместной работы.

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

    • Нарушение логики работы приложения.

      • Пример: в Trello пользователь может переместить карточку в колонку, но другой пользователь увидит её в старом состоянии в течение нескольких секунд.


6. Client-Centric Consistency Models (Клиентоцентричные модели)

  • Проблемы:

    • Сложность синхронизации.

    • Несогласованность на уровне всей системы.

  • Последствия:

    • Один клиент видит изменения, а другой — нет.

      • Пример: в Instagram пользователь видит свой новый пост сразу, но его друзья увидят его спустя несколько минут.

    • Разные версии данных на разных устройствах.

      • Пример: в Gmail письмо может быть помечено как прочитанное на телефоне, но на ноутбуке оно ещё отображается как непрочитанное.

    • Отложенная репликация может привести к несоответствиям.

      • Пример: в CDN обновлённая версия сайта может быть доступна в одном регионе, но старая версия продолжает кэшироваться в другом регионе в течение часа.


Обобщённые примеры для всех моделей:

  • Strong Consistency: финансовые транзакции и биржевые операции требуют мгновенной синхронизации данных.

  • Eventual Consistency: лайки, комментарии и уведомления могут обновляться с задержкой.

  • Linearizability: распределённые базы выполняют сложные транзакции с глобальной координацией.

  • Snapshot Isolation: аналитические запросы могут работать с устаревшими данными, но сохраняют изоляцию от текущих операций записи.

  • Causal Consistency: порядок сообщений в чатах и документах важен для корректной работы.

  • Client-Centric Models: мобильные приложения и кэш-системы обеспечивают согласованность только для отдельных пользователей, но не для всей системы.

Сводная таблица моделей согласованности

Тип согласованности

Проблемы

Последствия

Примеры приложений

Почему проблемы не критичны

Strong Consistency

- Высокая задержка - Низкая доступность

- Долгие задержки (банковские переводы до 1 мин) - Недоступность при сбое (блокировка транзакций)

Банковские системы, торговые биржи

Точность данных критична. Ошибка может привести к финансовым потерям.

Eventual Consistency

- Временная несогласованность - Конфликты данных

- Устаревшие данные (лайки до 30 сек) - Конфликты записей (профили перезаписываются)

Социальные сети, NoSQL базы данных

Небольшие задержки в обновлении данных не влияют на UX.

Linearizability

- Высокая стоимость - Сложность реализации

- Задержки (200 мс в Spanner) - Замедление работы кластера (секунды в Zookeeper)

Google Spanner, Zookeeper

Строгий порядок операций важен для предотвращения ошибок в критических системах.

Snapshot Isolation

- Фантомные чтения - Высокие ресурсы

- Пропуск новых данных (до 5 записей) - Рост потребления памяти (PostgreSQL, Snowflake)

Snowflake, PostgreSQL, MySQL

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

Causal Consistency

- Сложность отслеживания - Увеличение метаданных

- Неверный порядок сообщений (ответы раньше вопросов) - Задержка обновлений (Trello, Google Docs)

WhatsApp, Google Docs, Trello

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

Client-Centric Models

- Сложная синхронизация - Несогласованность системы

- Разные данные на устройствах (письма в Gmail) - Отложенная репликация (CDN обновляется до 1 часа)

Instagram, Gmail, CDN

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


Объяснение таблицы:

  • Проблемы – основные технические трудности, возникающие при использовании модели.

  • Последствия – реальные примеры задержек, устаревших данных и конфликтов.

  • Примеры приложений – системы и сервисы, где используется данная модель согласованности.

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

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

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

https://jepsen.io/consistency

https://www.researchgate.net/figure/Consistency-Models-based-on-Reference-14_fig2_331104869


4. Философские мысли о природе ограничений data-bounded масштабируемости. Осторожно, матан!

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

Конечная скорость распространения данных

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

Сюда отлично вписывается посыл, сформулированный мной в 1й части статьи:

Распространение данных / состояния по системе требует времени. Если требуется консистентность данных во всей системе то нужно ждать пока данные распространятся по всей системе. Очевидные способы борьбы за скорость в распределенной архитектуре

  • не требовать одновременной консистентности во всей системе (event sourcing, cqrs, no acid)

  • требовать консистентности данных, но лишь в ограниченных областях системы (bounded context, например в микросервисах) и не распространять данных за их пределы

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

  • отказ от распределенной архитектуры или объединение неудачно разделенных микросервисов

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

  • no ACID

Свойства ACID

ACID — это гарантии транзакций в базах данных:

  • Atomicity (атомарность): Все операции внутри транзакции выполняются как единое целое (или не выполняются вовсе).

  • Consistency (консистентность): Данные всегда остаются в согласованном состоянии.

  • Isolation (изоляция): Одновременные транзакции изолированы друг от друга.

  • Durability (устойчивость): Записанные данные сохраняются даже в случае сбоев.

Когда мы говорим об оптимизации, то ослабляем одно или несколько свойств ACID:

  • Ослабление Consistency приводит к eventual consistency (согласованность наступает со временем).

  • Ослабление Isolation позволяет выполнять больше транзакций параллельно за счет возможных конфликтов.

  • Ослабление Durability может ускорить операции записи, но приводит к риску потери данных.

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

CAP-теорема

CAP-теорема утверждает, что в распределенной системе невозможно одновременно обеспечить:

  • Consistency (согласованность): Все узлы видят одни и те же данные в одно и то же время.

  • Availability (доступность): Каждый запрос получает успешный ответ (без гарантии согласованности).

  • Partition tolerance (устойчивость к разделению): Система продолжает работать, несмотря на сбои связи между узлами.

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

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

Теорема PACELC

PACELC расширяет CAP-теорему, добавляя еще одну дихотомию:

IF P THEN (C or A), ELSE (C or L).

Если система сталкивается с сетевым разделением, т.е. временной недоступностью узла (P), то она должна выбрать между C (согласованностью) и A (доступностью).
Если же разделения нет (ELSE), то она должна выбрать между C (согласованностью) и L (задержкой, латентностью).

Пример: DynamoDB от AWS, в зависимости от конфигурации, позволяет выбирать между строгой согласованностью (strict consistency) или более низкой задержкой (low latency).

Практическое применение CAP и PACELC

CAP и PACELC чаще всего используются для выбора подходящей базы данных. Например:

  • Если вам нужна максимальная доступность и низкая задержка (например, для системы рекомендаций), вы можете выбрать систему типа Cassandra или DynamoDB.

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


5. Шаблоны CPU-bounded масштабирования

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

Горизонтальное масштабирование

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

Пример: Kubernetes и Docker позволяют легко управлять контейнерами, которые можно масштабировать в зависимости от нагрузки.

Параллельная обработка

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

Пример: MapReduce и его аналоги (Hadoop, Apache Spark) используются для обработки больших объемов данных параллельно на множестве узлов.

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

Асинхронная обработка

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

Пример: Использование очередей сообщений (RabbitMQ, Kafka) для выполнения длительных операций.

Оптимизация алгоритмов

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


6. Практические выводы

Интуитивно понятные эвристики для определения времени обеспечения консистентности данных

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

Оценка времени распространения данных

  • Максимальное время сети (Network Latency): Определите максимальное время, за которое данные могут быть переданы между самыми удаленными узлами в вашей системе. Это включает время на сетевую передачу, обработку на каждом узле и возможные задержки из-за загрузки сети.

  • Время на обработку (Processing Time): Оцените время, необходимое узлам для обработки входящих данных. Это может включать время на валидацию, запись в базу данных, и другие бизнес-операции.

  • Время на репликацию (Replication Time): Если вы используете репликацию, добавьте время, необходимое для синхронизации данных между репликами. Обратите внимание на стратегию репликации (синхронная или асинхронная) и её влияние на время.

Определение допустимой задержки (Tolerable Latency)

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

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

Выбор подходящего уровня консистентности

  • Strong Consistency: Если требуется немедленная консистентность, используйте синхронные операции и строгие гарантии ACID. Однако это может привести к снижению производительности и доступности.

  • Bounded Staleness, Session, Consistent Prefix и другие промежуточные варианты, где данные становятся консистентными в пределах определенного времени или количества операций. Подходит для сценариев, где допустима небольшая задержка, но важна предсказуемость.

  • Eventual Consistency: Если допустима задержка, рассмотрите асинхронные операции и eventual consistency. Это улучшит производительность и масштабируемость, но требует дополнительных механизмов для обработки конфликтов и восстановления состояния.

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

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

  2. Понимайте trade-offs. Каждый архитектурный паттерн имеет свои компромиссы. Например, микросервисы увеличивают изоляцию, но усложняют управление системой.

  3. Не изобретайте велосипед. Используйте готовые решения и инструменты (например, Kubernetes для оркестрации, Redis для кэширования, Kafka для обработки событий).

  4. Масштабируйте постепенно. Если текущие методы оптимизации перестают работать, переходите к более сложным подходам, таким как CQRS или микросервисы.

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

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

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

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

А также немножко про OAuth / OpenID / WebAuth, jwt, шифрование, kafka, SSO, web socket, REST.

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


  1. healfy
    12.01.2025 10:23

    Спасибо за статью, как и первая - очень интересно!


    1. Dhwtj Автор
      12.01.2025 10:23

      Спасибо.

      В итоге, я считаю что микросервисы переоценены. Особенно, как средство повышения быстродействия. Сейчас можно использовать до 2 процессоров по 128 ядер по 2 потока. Не хватит что-ли? И всего-то за 2-5 месячных зарплат программиста.

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

      Я описал менее травматичные способы масштабирования. И микросервисы тоже описал.

      Остальные архитектурные цели в других статьях.

      Хабр вообще рассчитан на 5 минутные статьи.


      1. brutfooorcer
        12.01.2025 10:23

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

        Как вы можете писать, что "микросервисы переоценены", если сами в предыдущей статье предложили решение на микросервисах?


        1. Dhwtj Автор
          12.01.2025 10:23

          Решение на микросервисах только для отдельных доменах и больше для безопасности (изоляции системы платежей), а аналитическая система всё равно отрезана из-за cqrs.

          Я же написал всё

          в плюсах МС никогда не было "повышения быстродействия"

          Щас поищем. Scalability наверняка там есть

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


          1. brutfooorcer
            12.01.2025 10:23

            Щас поищем. Scalability наверняка там есть

            Ну так это про масштабируемость. А это явно не слабая сторона микроскрвисов.

            Я же написал всë

            Вы обосновали выбор микросервисной архитектуры. Почему же вы выбрали именно эту архитектуру, если настолько разочарованы в ней и есть множество решений лучше?


            1. Dhwtj Автор
              12.01.2025 10:23

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

              Я разочарован именно таким штампом в мозгу.


              1. brutfooorcer
                12.01.2025 10:23

                Но именно эту мысль донести не получилось ни в этой статье, ни в предыдущей. Надо ли выделять МС с умом? Надо. Плох ли микросервисный подход от этого? Конечно, нет. У него свои плюсы и свои минусы, и при выделении нового микросервиса мы всегда должны определить - получим ли мы от этого больше, чем потеряем.

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


                1. Dhwtj Автор
                  12.01.2025 10:23

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

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

                  В результате, нафиг не надо никаких тысяч микросервисов с трудоёмкостью не более 2 человеко- месяца как я встречал во многих книжках


                  1. brutfooorcer
                    12.01.2025 10:23

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

                    Но думать, нужен ли для функциональности отдельный МС- надо всегда.


                    1. Dhwtj Автор
                      12.01.2025 10:23

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

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


                  1. brutfooorcer
                    12.01.2025 10:23

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

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


  1. healfy
    12.01.2025 10:23

    Спустя годы эксплуатации согласен с тем что микросервисы переоцены)


  1. lear
    12.01.2025 10:23

    Мне в таких статьях не нравится то, что они дают только поверхностное представление о подходах.

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

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

    Это на словах может быть легко развернуть кластер с микросервисами, либо наоборот, использовать эффективно все 64 ядра. Но по факту, знающему человеку нет особой разницы, 16 машин по 4 ядра, или одна на 64. Есть задача, есть ресурсы, есть существующая инфра. И уже от вводных начинаешь скакать и придумывать решение на компромиссах. Я не говорю что можно выполнить любую задачу из любых вводных, Я говорю о том, что большинство задач можно решить разными способами и построить разные архитектуры.

    Точно так же и в выборе монолит/микросервис. Если соблюдать простой принцип разделения ответственности, то в 90%+ случаев этого будет достаточно для выделения отдельных БЛ в сервисы.


    1. Dhwtj Автор
      12.01.2025 10:23

      То есть вам нужны примеры перехода от монолита к микросервисам и наоборот от микросервисов к укрупнению в монолит(ы)? Да ещё в большом количестве? Да ещё при прочих равных?

      Ну, этим я вряд-ли вас порадую. Хотя, на Хабре можно найти кейсы как в одну так и в другую сторону.

      Я вот не видел хорошо обоснованных переходов на микросервисы


      1. lear
        12.01.2025 10:23

        Я от вас не жду этого =)

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

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

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


        1. Dhwtj Автор
          12.01.2025 10:23

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

          Но судя по статьям озон тут и по моему собеседованию в озон там слишком увлеклись. Тысячи, тысячи их! )))


          1. lear
            12.01.2025 10:23

            Пусть развлекаются как хотят) Особенно если вносят вклад в сообщество.

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


      1. murkin-kot
        12.01.2025 10:23

        То есть вам нужны примеры перехода от монолита к микросервисам и наоборот

        Мне кажется посыл был такой - аудитории нужны очень простые сказки. Сложные не нужны. Краткие и ёмкие тоже не нужны.

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

        Ну и по вашим выводам:

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

        Баланс здесь очень толстый. Если затраты на IT составляют, скажем, 10% от расходов в десятки миллиардов рублей, то плюс-минус несколько сот миллионов никто не заметит. И этим активно пользуются, изобретая микросервисы, велосипеды, ну и прочих монстров.

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

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

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

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

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


        1. Dhwtj Автор
          12.01.2025 10:23

          Обойдутся без разжевывания

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

           не давая критериев эффективности, в том числе денежных

          Делал уже такое https://habr.com/ru/articles/803295/

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


        1. lear
          12.01.2025 10:23

          В целом верно, но ещё дополнение =)

          Если свести мой посыл до пары предложений, то он будет звучать примерно так:

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

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