Разработка приложений с использованием микрослужб

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

Ниже приведены примеры изменяющихся бизнес-потребностей:

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

Эти бизнес-потребности определяют способ сборки приложений.

Дополнительные сведения о подходе Azure к микрослужбам см. в блоге Microservices: An application revolution powered by the cloud (Микрослужбы: облачная революция в приложениях).

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

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

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

В эпоху клиент-серверной архитектуры разработчики создавали многоуровневые приложения с использованием определенных технологий на каждом уровне. Для обозначения подобных подходов возник термин "монолитные приложения". Интерфейсы находились как бы между уровнями, а в рамках самого уровня компоненты были более тесно связаны. При разработке и разделении классы компилировались в библиотеки, а библиотеки объединялись в несколько исполняемых файлов и библиотек DLL.

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

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

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

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

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

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

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

Сравнение подходов к разработке приложений

Разработка приложений на платформе Service Fabric

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

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

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

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

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

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

Что такое микрослужба?

Существует много определений микрослужб. Вот основные общепринятые характеристики микрослужб:

  • Инкапсуляция сценария клиента или бизнес-сценария. Какую задачу вы решаете?
  • Разработка небольшими командами разработчиков.
  • Код на любом языке программирования, работа с любыми платформами.
  • Составляющие компоненты — код и состояние (при его наличии), можно развертывать и масштабировать, а также управлять их версиями независимо друг от друга.
  • Взаимодействие с другими микрослужбами с помощью четко определенных интерфейсов и протоколов.
  • Наличие уникальных имен (URL-адресов), которые можно использовать для определения их расположения.
  • Обеспечение стабильности работы и доступности в случае сбоя.

Иными словами:

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

Код на любом языке программирования, работа с любыми платформами

Разработчики могут выбирать язык или платформу в зависимости от своих навыков или потребностей разрабатываемой службы. Для некоторых служб преимущества в отношении производительности, обеспечиваемые языком C++, могут иметь большее значение, чем все остальное. В других случаях может быть важнее простота управляемой разработки на C# или Java. В некоторых случаях может потребоваться использовать определенные партнерские библиотеки, технологии хранения данных или средства предоставления службы клиентам.

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

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

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

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

Хранилище состояний в разных подходах

Хранилище состояний платформы Service Fabric

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

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

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

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

Микрослужбы поддерживают управление версиями. Разные версии микрослужбы могут выполняться параллельно. Более новая версия микрослужбы может вызвать сбой во время обновления. В таком случае нужно выполнить откат до более ранней версии. Управление версиями также применяется при A/B-тестировании, при котором разные пользователи используют разные версии службы. Например, микрослужбы часто обновляют для определенной группы клиентов, которые тестируют новые функциональные возможности, прежде чем микрослужбы будут развернуты для широкой аудитории.

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

За последние 10 лет опубликована богатая информационная база по сервисноориентированной архитектуре, которая описывает шаблоны взаимодействия. Сейчас, как правило, для взаимодействия между службами используется REST, протоколы HTTP и TCP, а также формат сериализации XML или JSON. С интерфейсной точки зрения прослеживается стойкая аналогия с веб-дизайном. Но вам ничто не мешает применять бинарные протоколы или собственные форматы данных. Однако учитывайте, что в таком случае вашими микрослужбами (если эти протоколы и форматы не появятся в открытом доступе) будет сложнее пользоваться.

Уникальное имя (URL-адрес), используемое для распознавания расположения

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

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

Стабильность работы и доступность в случае сбоя

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

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

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

Передача информации о работоспособности и диагностических данных

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

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

Рекомендации по проектированию микрослужб в Azure

Рекомендации по проектированию и созданию микрослужб в Azure см. в Центре архитектуры Azure.

Платформа микрослужб Service Fabric

Платформа Azure Service Fabric создана в рамках перехода корпорации Майкрософт от предоставления готовых продуктов, зачастую монолитных, к предоставлению служб. При ее создании учитывался опыт разработки и эксплуатации масштабных служб, таких как База данных Azure SQL и Azure Cosmos DB. Платформа продолжает развиваться по мере внедрения во множестве новых служб. Service Fabric работает не только в среде Azure, но и в автономных развертываниях Windows Server.

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

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

  • Платформа, которая предоставляет системные службы для развертывания, обновления, обнаружения и перезапуска служб, в которых произошел сбой, а также обнаружения служб, маршрутизации сообщений, управления состоянием и мониторинга работоспособности.
  • Возможность развертывания приложений, выполняемых в контейнерах или в процессах. Service Fabric — это контейнер и оркестратор процессов.
  • Эффективные программные интерфейсы, позволяющие создавать приложения как микрослужбы: ASP.NET Core, Reliable Actors и Reliable Services. К примеру, вы можете получать информацию о работоспособности и данные диагностики, а также пользоваться преимуществами встроенных средств, обеспечивающих высокую доступность.

Service Fabric не зависит от способа создания службы, то есть, можно использовать любую технологию. Однако эта платформа предоставляет встроенные API программирования, которые облегчают создание микрослужб.

Перенос существующих приложений в Service Fabric

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

  1. начать с традиционного монолитного приложения.
  2. Миграция. Использование контейнеров или гостевых исполняемых файлов для размещения существующего кода в Service Fabric.
  3. Модернизация. Добавление новых микрослужб вместе с существующим контейнерным кодом.
  4. Инновации. Разбиение монолитного приложения на микрослужбы в зависимости от потребностей.
  5. Преобразование приложения в микрослужбы. Трансформация существующих монолитных приложений или создание новых приложений с нуля.

Миграция приложения на микрослужбы

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

Рассмотрим примеры для каждого из этих этапов.

анализа
Многие компании переносят существующие монолитные приложения в контейнеры по двум причинам:

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

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

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

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

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

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

Подходят ли микрослужбы моему приложению?

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

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

Дальнейшие действия