Способ и логика взаимодействия элементов внутри ИТ-инфраструктуры наделяет ее определенными свойствами. Например, масштабируемостью и гибкостью или наоборот — неповоротливостью и уязвимостью к ошибкам. Понимание этих свойств и корреляций – ключ к грамотному выбору конкретных подходов и инструментов для интеграций.
В противном случае, компания рискует стать заложником инструмента — например внедрить ESB-слой для упрощения интеграций, но при этом так и не преодолеть ограничения старого-доброго монолита.
Поэтому в этой статье разберем теоретическую базу: понятия связности, связанности модулей и инкапсуляцию. А еще предложим конкретные критерии для оценки гибкости ИТ-инфраструктуры и стресс-тест для проверки своего контура на монолит.
Связанность, связность и инкапсуляция в микросервисной архитектуре
Микросервисы позволяют обновлять и запускать отдельные функции. Например, систему управления пользователями или модуль обработки платежей без влияния на другие части приложения.
Чтобы построить работающую микросервисную архитектуру, надо четко определить границы модулей. В контексте качества границ микросервисов существует три основных концепции:
1. Связанность (coupling) — мера того, насколько взаимозависимы разные подпрограммы или модули. Другими словами, способ и степень взаимозависимости между программными модулями внутри отдельно взятой ИТ-архитектуры.
Связанность бывает сильной (high coupling) и слабой (low/loose coupling).
Сильная связанность (high coupling) означает высокую зависимость между модулями, что усложняет их понимание, изменение и тестирование. Воспринимается как серьезный недостаток системы, а еще является одним из характерных свойств монолитных систем.
Слабая связанность (low coupling) — состояние системы, когда изменения в одном модуле не требуют изменений в другом. Слабо связанный сервис имеет необходимый минимум сведений о сервисах, с которыми ему приходится работать и отвечает только за свои данные в общем контексте. Слабо связанный сервис обладает тремя главными свойствами:
- Малое число зависимостей между подсистемами (модулями)
- Слабая зависимость одного модуля от изменений в другом модуле.
- Легкость повторного использования подсистем.
2. Связность (cohesion) — степень взаимосвязанности элементов внутри модуля: то, насколько задачи, выполняемые одним программным модулем, связаны друг с другом.
Как и со связанностью, выделяют два уровня связности:
Сильная связность (high cohesion) — состояние, когда обязанности компонентов внутри одного модуля хорошо согласованы между собой и он не выполняет огромных объемов работы. В отличие от сильной связанности (где речь идет о связанности разных модулей), сильная связность внутри одного модуля — позитивный признак.
Слабая связность (low cohesion) — состояние, когда один модуль выполняет много разнородных функций или несвязанных между собой обязанностей. Это свойство модуля приводит к следующим проблемам:
- Трудность понимания
- Сложность при повторном использовании
- Сложность поддержки
- Ненадежность, постоянная подверженность изменениям
Понятия связанности и связности тесно переплетены. Связанность представляет отношения между объектами через границы модулей. Связность же применима к отношениям между функциональными объектами внутри границ модуля. Эти два понятия важно не путать. В этой статье мы фокусируемся на категории связанности как индикатора гибкой ИТ-архитектуры.
Идеальный вариант — сочетание слабой связанности между модулями сервиса и сильной связности между компонентами внутри модуля. То есть, когда модуль имеет небольшое число внешних связей и отвечает за решение близких по смыслу задач.
3. Инкапсуляция — это скрытие деталей реализации внутри микросервиса. Эти детали как бы помещают в капсулу, чтобы их нельзя было повредить извне. Идея в том, пользоваться только теми данными, которые доступны, и не лезть внутрь.
То есть, сервису должно быть известно минимум контекста и данных о другом сервисе, с которым он общается. И пользоваться он должен только тем, что по умолчанию доступно.
Например, Дэвид Парнас, канадский информатик и один из создателей концепции модульности в ПО, рассматривал связи между сервисами, как предположения, которые они делают друг о друге. Чем меньше таких предположений, тем легче изменить изменить одну часть сервиса, не затрагивая другую. Снижение количества связей и информации сервисов друг от друге позволяет ускорить разработку, сделать сервис более прозрачным и гибким.
Что все это значит на практике и причем тут общий контекст?
Прежде чем переходить от сложной теории к практике, введем категорию контекста.
В разработке ПО есть два контекста — контекст приложения и контекст предприятия. Сервис-ориентированная архитектура, микросервисная архитектура и монолитная архитектура построены вокруг контекста.
Например, заказы в контекстах CRM-системы и интернет-магазина (e-shop) — разные вещи. Атрибуты заказа в CRM-системе и интернет-магазине отличаются:
Для контекста предприятия о заказе важно знать только ограниченный набор параметров — например, идентификатор, клиента и сумму. Все остальные атрибуты CRM-системы контексту предприятия не нужны.
Чтобы объяснить, чем отличаются сильная и слабая связанность на практике, рассмотрим два варианта обмена информацией между CRM и интернет-магазином.
- Для обмена данными CRM и интернет-магазин должны понимать друг друга. Процесс начинается с отправки заказа из интернет-магазина в брокер, а затем другая система берет данные и переводит их в свой внутренний язык. Но для этого другой системе нужно знать контекст первой — это и есть сильная связанность или монолит. Контексты перемешиваются, это усложняет интеграцию, и получается подход «точка-точка».
- По каким принципам общение между сервисами происходило бы в случае слабой связанности? Каждая система «думала» бы, что она одна в предприятии и отвечала бы только за то, что именно она передает в контекст предприятия. Сервисные шины (ESB) — инструмент для реализации интеграций в слабо связанной архитектуре.
Главные признаки слабо связанной архитектуры
1. Быстрая масштабируемость.
Слабосвязанную систему легко масштабировать и добавлять новые сервисы — другие системы не знают о том, что вы добавили что-то в общий контекст и продолжают управлять своим бэклогом самостоятельно.
В сильно связанной или монолитной архитектуре быстро наступает момент, когда разработчики оказываются перегруженными бесконечными доработками интеграции, кросс-командным тестированием, выгрузками заказов и т.д. Но все равно что-то продолжает работать не так, и в какой-то момент изменения становятся еще и экономически невыгодными.
Например, в 2001 году Amazon столкнулся с подобной ситуацией→, когда их монолитная архитектура стала причиной больших задержек в выпуске новых фич и трудностей в управлении изменениями. В итоге, переход на микросервисы улучшил масштабируемость и скорость разработки, хотя и потребовал от Amazon значительных инвестиций в инфраструктуру и управление.
2. Отказоустойчивость.
В слабо связанной интеграции все ошибки инкапсулированы за счет небольшого количества связей между сервисами. При отказе какого-то одного потока, все остальные продолжают работать как обычно. При этом система без проблем справляется даже с пиковыми нагрузками.
3. Простота мониторинга и высокая скорость решения инцидентов.
В сильно связанных системах мониторингом и решением инцидентов занимается супер-синьор, часто перегруженный, так как только он может разобраться в спагетти-связях→ между сервисами и найти источник ошибки.
В слабо связанных системах мониторинг осуществляется просто — его можно делегировать техподдержке. А еще можно настроить автоматические алерты на превышение каких-то параметров.
4. Высокая скорость изменений.
Доработка любого из сервисов никак не скажется на работе всех остальных, а новые потоки данных можно запускать быстро. Компании со слабо связанной архитектурой быстрее внедряют новые сервисы. Чем быстрее внедряются инновации, тем меньше упущенная выгода. По оценкам экспертов, более 80% компаний в мире уже используют микросервисы→, чтобы повысить шансы на победу в конкурентной гонке.
5. Актуальность данных в системах.
Тут возвращаемся к понятию общего контекста и примеру с CRM-системой и интернет-магазином в рамках одного предприятия. В монолитных системах каждый запрос от одной системы другой нужно переводить в собственный контекст. Это приводит к ошибкам в данных, потерям и неточностям. В слабосвязанных контурах такой проблемы нет, потому что каждая система отвечает только за передачу своих данных в общий контекст.
6. Защита от вендорлока (привязки к поставщику).
Наличие интеграций у конкретного из сервисов с какими-то другими не является препятствием для замены или доработки конкретного сервиса. А интеграцию можно делегировать не только команде разработки внешнего сервиса или вендору, но и любому разработчику и подрядчику.