Обычно, разработка начинается с монолитного приложения. Да, и вообще, по lean-startup, рекомендуется, продуктовый сервис разрабатывать монолитного и походу развития продукта отмечать, на какие сервисы он будет разбит. Так, узким местом может оказать часть сервиса, к которой требования изменили пользователи и именно она потребует выделения в отдельную часть сервиса для горизонтального масштабирования.
* Представим, у нас есть монолитное приложение, то есть приложение, состоящее из одного или нескольких тесно-связанных элементов. Наша задача обеспечить непрерываность производственного процесса, например, за счёт DevOps практик, лёкость его развития, например, за счёт паттернов проектирования.
* Следующим этапом является разбиение монолитного приложения на сервисы и замена PC (Procedure Call) на RPC (Remote Procedure Call), то есть с локальных выводов на сетевые.
* Разбиением мы достигли увеличение масштабируемости и скорости производственного цикла (внедрение новых сотрудников, разработки, тестирования, выкат в продуктовую среду). Но мы потеряли в безопасности (трафик может быть перехвачен), в надёжности (пакеты по сети могут быть доставлены или с задержками, а иногда и не доставлены вообще). Для решения этой проблемы нам у каждого сервиса необходимо создать библиотеку, которая бы обеспечивала безопасность (шифрование, авторизацию, аутентификацию) и надёжность (повторы соединений, timeout, circuit breaker). Для реализации отказоустойчивости соединения можно воспользоваться библиотекой Hystrix, а для решения проблем с безопасностью – встройка сертификатов в сервисы.
* Теперь, стоит вопрос как разрабатывать, обновлять сервисы, поддерживать сервисы на различных языках, уменьшить нагрузку с разработчиков оп обеспечению их сервисов настройкой Hystrix и контролем маршрутизации. И подхода здесь два: централизация и автоматизация децентрализации. При централизации создаётся единый сервер, к которому подключаются все сервисы, и он содержит в себе всё необходимое по управления трафиком, по обеспечению безопасности и надёжности соединений. Сервера с такой функциональностью называются корпоративная шана данных. Положительными качествами такого подхода является: готовы продукт (достаточно подключиться к адаптеру и указать маршрут у панели управления), функциональность (имеется различные адаптеры и функциональный маршрутизатор), а отрицательными качествами: ограничение по масштабируемости, единая точка отказа на уровне доступности (отказ ведеёт в неработоспособности всех сервисов, хотя, корпоративная шина данных поставляется в виде кластеров и имеет высокий уровень отказоустойчивости). Другим решением является микросервисная архитектура. Достоинствами является: масштабируемость, единая точка отказа только на уровне управления (управляющий сервис только меняет конфигурации клиентских библиотек), наличие оркестрации сервисов (Service Discovery, автоматическое горизотнальное масштабирование, балансировка), а недостатком: слабая функциональность. Независимостиь от языков обеспечиваются по разному: КСШ – адаптерами по HTTP, а SideCar контейнерами по HTTP (для Spring Cloid это не так – зависит от Java).
Внедрение микросервисов начинается с бизнеса, когда маркетинг начинает делать эксперименты – запрашивать фичи в виде MVP, потом тестировать на рынке, после либо браковать (что редко), либо дорабатывать. Доработка требуется как после подтверждения предположения, так и ошибочного в виде корректировки. Для службы эксплуатации это означает выкатку огромного количества фич, которые были разработаны с единственной целью – успеть к дедалайну и могут обрушить основное приложение – монолит. Эта служба пытается запускать эти изменения в изолированной среде в виде отдельного функционала, для чего просит отдел разработки, разрабатывать их отдельно – в виде микросервисов.
Нужно разделять два уровня разделения: технологическое и доменное. Технологические особенности в работе едины, так как что сервисы, что его компоненты, если он разбит на составные части технологически запускаются и поддерживается одинаково. Но, в отличии от сервисов, которые должны быть минимально взаимосвязаны с другими сервисами и должны обеспечивать определённое API и SLA, то компоненты сильно связанны. Причиной разделения на компоненты имеют технологическую природу. Например, интернет-магазин содержит сервисы, такие как сама интернет-витрина, сервисы оплаты, складские сервисы, а интернет-витрина представляет из себя сервис на CMS Joomla! и систему управления базой данных (СУБД) MySQL. Здесь разделение сервиса на составные части произошло из-за разных программных продуктов, написанных на разных языках программирования. При этом, для заказчика это единый сервис на CMS Joomla!, выполняющий единую функцию предоставления интерфейса для заказа пользователям в онлайн, предоставляемый хостингом как единый сервис (по отдельности не будет работать), может работать как каталог товаров без других сервисов (оплаты, заказа). С технологической точки зрения компоненты сервисы:
* По одиночки не функциональны; * Сильно связанны, так как на каждый запрос к CMS формируется множество запросов; * Интерфейсы взаимодействия сложны и разнообразны – тут применяется даже не API, а язык взаимодействия SQL; * Сильно связанны функционально через сложное техническое API – для пользователя известно лишь поддерживаемая совместимость одних версий CMS с другими версиями СУБД.
Разделение системы на микросервисы начинается с анализа их границ, анализ выгод от разделения и привнесённых сложностей распределённой системой. Отделять микросервисы лучше при комбинации необходимости:
* Технологической необходимости, например, большая нагрузка, которую сложно выдержать без отделения, например, масштабированием, другой вид поддержки (SLA);
* Для бизнеса выделяемый сервис уже является отдельной и мало зависимой функцией – далее рассмотрим подход DDD (model-driven design + ubiquitous language) к реализации микросервисов;
* Необходима смена технологической платформы.
Микросервис отвечает следующим характеристикам, по мнению М. Фаулера (martinfowler.com). Их можно свести к:
* 1. Должен из себя представляет компонент или сервис. Каждый микросервис – законченный полноценны независимый сервис с точки зрения разработчика, системного администратора и пользователя. Он должен обладать возможностью быть легко заменённым на другой, как в коде разработчика, как в процессе работы (должны быть), так и представлен другим или убран в интерфейсе пользователя. Не выполнения условий заменимости на разных уровнях приводят к одному сервису разделённому на части – распределённому монолиту;
* 2. Организация бизнес-возможностей;
* 3. Продукты – не проекты;
* 4. Умные конечные точки и глупые связи. Не требующая сложной интеграции с отлаженными сервисами (интеграцию сложных систем занимается сервис ориентированная архитектура SOA);
* 5. Децентрализованное управление. Здесь имеется в виду оркестрация, например, Kubernetes, управление сетью, например, Istio, управление доставкой, например, KNative;
* 6. Децентрализованное управление данными. В силу самодостаточности сервиса и независимости от других он должен иметь независимое состояние – базу данных, а чтобы и выбор системы управления базой данных был независимы – есть и её свою;
* 7. Автоматизированная инфраструктура. Процесс деплоя, масштабирования и откатов должен быть автоматизированы, что позволяет быстро автоматически откатываться, фиксировать в коде изолированность работы сервиса;
* 8. Предусмотрен отказ в работе. Для визуализации отказов можно посмотреть на Jaeger и Prometheus, для локализации проблем сервисы должны быть изолированы, представлять один единый сервис, что позволяет изолировать, ограничить пагубное воздействия на другие сервисы при отказе и автоматизировать откат;
* 9. Эволюционирующий дизайн. Система наращивает отростки в виде сервисов – обрастает ими, при этом не требуется изменение её структуры. Neal Ford и Rebeca Parsons в "Микросервисы как эволюционирующая архитектура" ориентируются на постоянные улучшения.