Статьи
December 29, 2023

Анализ архитектуры микросервисов

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

Избегайте зависимостей и оркестровки

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

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

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

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

Соображения

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

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

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

Анализ паттерна

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

Общая ловкость

Рейтинг: Высокий

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

Простота развертывания

Рейтинг: Высокая

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

Тестируемость

Рейтинг: Высокий

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

Производительность

Рейтинг: Низкая

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

Масштабируемость

Рейтинг: Высокий

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

Простота разработки

Рейтинг: Высокая

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