Микросервисы - быстрый цикл разработки и постоянный выпуск

По материалам книги Программирование Cloud Native. Микросервисы, Docker и Kubernetes (Иван Портянкин, cloud-native-docker-k8s)

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

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

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

Основные положения концепции Cloud Native

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

Реализовать это возможно с помощью так называемых “микросервисов” (microservices), слабо связанных между собой компонентов единой системы или приложения. Они обмениваются данными через сеть, используя стандартные сетевые протоколы, как правило это протокол HTTP и стандарт REST. Разработка и обновление одного микросервиса никак не затрагивает остальные части системы. Микросервисы связываются друг с другом через сетевые порты и абстрактные протоколы, и каждый из них может быть написан на любом подходящем языке и технологии. Обновляются и перезапускаются они также независимо. Микросервисы часто противопоставляются единому, большому серверному приложению, так называемому “монолиту” (monolith).

Одно из преимуществ приложения, разбитого на модули и микросервисы, работающие из собственных контейнеров - тонко настроенное горизонтальное масштабирование. Появляется возможность выделить наиболее нагруженную часть системы и запустить для ее сервисов и компонентов столько экземпляров, сколько необходимо для обработки текущей нагрузки. Для этого требуется практически неограниченная вычислительная мощность, растущая по требованию (ее еще называют эластичной) - эту мощь обеспечивают коммерческие провайдеры облака, такие как Google Cloud (GCP), Amazon Web Services (AWS), SberCloud, Yandex.Cloud.

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

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

Контейнеры (containers) - легкая виртуализация в пределах одной операционной системы (как правило Linux), не требующая “тяжелых” виртуальных машин, включающих в себя полную отдельную операционную систему. Контейнеры позволяют множеству микросервисов незаметно друг для друга работать на одном сервере, в пределах одной операционной системы.

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

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

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

Микросервисы - быстрый цикл разработки и постоянный выпуск

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

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

Эластичность и практически неограниченная вычислительная мощность облака дает нам возможность разбить приложение на логические компоненты и запускать их и управлять ими индивидуально. При необходимости легко увеличить пропускную способность приложения, увеличив количество экземпляров компонентов (работающих в виде микросервисов), испытывающих наибольшую нагрузку. Это так называемое горизонтальное масштабирование (horizontal scaling или scaling out) - при работе в облаке его возможности практически безграничны, при условии выбора удачной архитектуры приложения, дающей возможность разбить его вычислительные потоки на независимые части. Вертикальное масштабирование же подразумевает рост мощности одного сервера и его аппаратных возможностей, что крайне ограничено, и более того, мощные серверы обычно очень дороги.

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

Гораздо меньший размер и менее связанная с другими компонентами функциональность позволяет программистам быстро проводить в жизнь новые идеи, рефакторинг кода, и пробовать новые подходы и процессы разработки. Разумный размер кода делает процесс разработки эффективным и удобным. Это же позволяет проще настроить системы постоянного контроля качества и развертывания сделанных изменений на сервере (CI/CD, continuous integration and delivery), и сделать их работу прозрачной и высокопроизводительной, позволяя программистам быстро проверить, было ли их последнее изменение удачным.

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

“Невозможно описать термин “микросервис”, потому что не существует даже словарного запаса для этой области. Вместо этого мы опишем список типичных черт микросервисов, но сделаем это со следующей оговоркой - большинству микросервисных систем присущи лишь некоторые из приведенных черт, но не всегда, и даже для совпадающих черт будут значительные различия от канона.” Мартин Фаулер (Martin Fowler), одно из первых выступлений, посвященных глубокому анализу микросервисов).

Архитектура на основе сервисов (SOA)

Более гибким решением является разработка на основе компонентов, отделенных друг от друга, прежде всего на уровне процессов, в которых они исполняются. Архитектуру подобных проектов называют ориентированной на сервисы (service oriented architecture, SOA).

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

Часто говорят, что классическая архитектура на основе сервисов отличается от ставших популярными сейчас “микро”-сервисов тем, что многое отдает на откуп “посредникам” (middleware), например системам обмена, настройки и хранения сообщений между компонентами и сервисами, так называемым “интеграционным шинам” (ESB, enterprise service bus). Микросервисы же эпохи облака минимизируют зависимость от работы со сложными посредниками и их правилами и проводят свои операции напрямую друг с другом.

Микросервисы по Мартину Фаулеру

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

Микросервисы - это использование компонентов (зависимостей, библиотек и модулей) своего приложения не внутри одного, единого процесса приложения, а запуск их в отдельных, собственных процессах, и доступ к ним не напрямую, а через сетевые вызовы RESTful API HTTP / GRPC.

Вся логика в обязательном порядке должна находиться внутри микросервисов (“разумные” точки доступа к сервису, smart endpoint), даже если она повторяется в различных микросервисах. Сеть (и любой механизм передачи данных в целом), должна только передавать данные, но не обладать никакой логикой (как еще говорят, “неразумные” линии передачи данных, dumb pipes).

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

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

comments
comments powered by Disqus