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

Часть 2: Различные скорости изменений 

Часть 3: Независимые жизненные циклы

Часть 4: Независимая масштабируемость

Часть 5: Изоляция сбоев

Часть 6: Упрощение внешних зависимостей

Часть 7: Свобода выбора подходящих технологий для работы

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

В наши дни вы не сможете даже провести маркером по доске, чтобы не задеть кого-нибудь, говорящего о микросервисах. Разработчики изучают пророческую книгу Эрика Эвана Domain Driven Design. Команды рефакторят монолитные приложения, ищут ограниченные контексты и определяют вездесущий язык. И хотя существует бесчисленное количество статей, видеороликов и выступлений, помогающих перейти на микросервисы, лишь немногие из них уделяют сколько-нибудь значительное время вопросу о том, должно ли данное приложение быть микросервисом.

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

Пожалуйста, относитесь к микросервисам ответственно

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

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

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

1. Различные скорости изменений

Части вашей системы должны развиваться с разной скоростью или в разных направлениях? Тогда разделите их на микросервисы. Это позволит каждому компоненту иметь свой независимый жизненный цикл.

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

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

2. Независимые жизненные циклы

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

При меньшем объеме тестировать микросервис гораздо проще. Я помню один проект с набором регрессионных тестов продолжительностью 80 часов! Само собой разумеется, мы не часто проводили полное регрессионное тестирование (хотя очень хотели бы этого). Микросервисный подход поддерживает мелкомодульное точное регрессионное тестирование. Это сэкономило бы нам бесчисленное количество часов. И мы бы быстрее выявили проблемы.

Тестирование - не единственная причина, по которой можно выделить микросервис. В некоторых случаях к микросервисной архитектуре нас может подтолкнуть деловая необходимость. Рассмотрим пример с монолитом Widget.io.

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

Но как отдельный микросервис, Project X (показанный ниже) может иметь свой собственный пайплайн для внедрения. Такой подход позволяет нам быстро выполнять итерации и использовать новые возможности для бизнеса.

3. Независимая масштабируемость

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

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

Скорее всего, функциональность администрирования аккаунтов (Account Administration) не испытывает такой нагрузки, как система обработки заказов (Order Processing). В прошлом приходилось масштабировать весь монолит для поддержки самого нестабильного компонента. Такой подход приводит к увеличению затрат на инфраструктуру, поскольку мы вынуждены "превышать резерв" для наихудшего сценария работы только части нашего приложения.

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

4. Изолированный сбой

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

Если снова обратиться к образцу Widget.io Monolith, то функциональность инвентаризации (Inventory) взаимодействует с устаревшей складской системой, которая не отличается высокой надежностью. Можно сохранить наш уровень сервиса для обеспечения доступности путем рефакторинга модуля Inventory в микросервис. Возможно, потребуется добавить некоторую избыточность, чтобы учесть нестабильность работы складских систем. Также можно внедрить некоторые механизмы согласованности, например, кэширование инвентаризации в Redis. Но пока что перехода на микросервисы достаточно для защиты от низкой производительности из-за ненадежной сторонней зависимости.

5. Упрощение взаимодействия с внешними зависимостями (принцип, также известный как паттерн "Фасад")

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

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

6. Свобода выбора подходящей технологии для работы

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

ВНИМАНИЕ: этот принцип не является лицензией на использование всех технологий подряд! Дайте рекомендации своим командам по выбору технологий. Слишком большое количество разрозненных стеков увеличивает когнитивную нагрузку и может быть хуже, чем стандартизация по типу модели "один размер подходит всем". Поддерживать актуальность библиотек сторонних разработчиков для одного стека достаточно сложно. Умножьте эту работу на четыре или пять, и вы получите достаточно тяжелое организационное бремя. Делайте то, что работает, и сосредоточьтесь на "проторенных путях", которые вы знаете, как поддерживать.

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

Проверка культуры

Все это было обсуждение технологии. Теперь что насчет культуры?

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

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

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

Подумайте также о том, какую инфраструктуру вы предоставляете. Команды, которые сосредоточены на самообслуживании и оптимизации потока создания ценности, часто принимают парадигму микросервисов. Такие платформы, как Pivotal Cloud Foundry, помогают вашим командам быстро развертывать сервисы, тестировать и дорабатывать их в течение нескольких минут, а не недель (или месяцев). Разработчики могут развернуть инстанс одним нажатием кнопки - практика, которая способствует экспериментам и обучению. Buildpacks автоматизируют управление зависимостями. Это означает, что разработчики и операторы могут сосредоточиться на предоставлении бизнес-ценностей.

Наконец, давайте зададим два конкретных вопроса о приложении:

  • Имеет ли это приложение несколько владельцев бизнеса? Если система обладает несколькими независимыми, автономными владельцами бизнеса, то у нее есть два разных источника изменений. В такой ситуации может возникнуть конфликт. С помощью микросервисов вы можете добиться "независимых жизненных циклов" и удовлетворить обе эти различные заинтересованные стороны.

  • Принадлежит ли это приложение нескольким командам? "Стоимость координации" для нескольких команд, работающих над одной системой, может быть высокой. Вместо этого определите для них API. После этого каждая команда может построить независимый микросервис, используя Spring Cloud Contract или Pact для тестирования контрактов потребителей сервиса.

Ответ "да" на любой из этих вопросов должен подвести вас к микросервисному решению.

Подведение итогов

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

Готовы экспериментировать с микросервисами на Pivotal Cloud Foundry уже сегодня? Ознакомьтесь с Small Footprint, PCF Dev или воспользуйтесь бесплатной пробной версией Pivotal Web Services. Пока вы здесь, ознакомьтесь с нашей страницей, посвященной микросервисам, и этим техническим документом "Запуск микросервисов на Pivotal Cloud Foundry".


Материал подготовлен в рамках курса «Системный аналитик. Advanced». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

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


  1. Vasily_T
    08.09.2021 14:09

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