Макро-польза микро-сервисов: мост от legacy-архитектур к современному IT
- Блоги, 17 марта 2019 в 1:32
Рассказывает Антон Херувимов, Technology Delivery Lead в компании Accenture Russia.
Цифровая трансформация, новые возможности digital-инструментов и архитектуры современных ИТ-систем создают парадигму современных технологий (New IT — так называет её компания Accenture). Она включает в себя самые продвинутые технологии (облака, ИИ, аналитику данных, машинное обучение и т. д.) и процессы (Agile, DevOps и Design Thinking), а также подразумевает несколько стадий трансформации сложной ИТ-инфраструктуры крупных компаний. Одним из первых шагов к её реализации становится адаптация слоя ИТ-микросервисов на базе существующих legacy-платформ.
В статье рассказываем, как работать с микросервисами, поддерживая развитие старой ИТ-инфраструктуры и создавая гибкость её новых элементов в максимально эффективном ключе.
Микросервисы для большого ИТ-будущего
Термин «микросервисная архитектура» (Microservice Architecture) обрёл популярность в последние несколько лет. Это способ разработки приложений через объединение независимо развёртываемых ИТ-сервисов. Такой подход позволяет построить вокруг сложившихся бизнес-процессов и потребностей автономный сервис. Благодаря использованию стандартных протоколов взаимодействия, например HTTP-вызовов через API и брокеров сообщений, микросервисы могут быть написаны на разных языках программирования и использовать различные технологии хранения БД.
При традиционном подходе к созданию ИТ-системы по принципу «монолита» управление больше фокусируется на технологиях. Команды формируются по технологическому принципу — разработчики, администраторы БД, аналитики данных и т. д. Такой подход вызывает серьёзные трудности при реализации бизнес-функциональности в ИТ-систему, поскольку их нужно производить через кросс-командное взаимодействие.
Микросервисы позволяют формировать независимые (agile) кросс-функциональные команды с фокусом на определённой бизнес-задаче вместо технологии. Такие команды самодостаточны, хорошо сфокусированы, используют те подходы и технологии, которые максимально эффективны в конкретном случае и позволяют переключиться с «проектного управления» на «продуктовое».
В микросервисах каждый элемент выполняет только одну функцию и может быть независимо от других сервисов «донесён до production», поэтому, чтобы внести изменения в решение, не нужно перестраивать весь алгоритм. Если возникает необходимость в обновлении, перестройке, отладке и других коррективах, то достаточно осуществить их на конкретном участке ИТ-системы. Например, если необходимо добавить новый способ доставки или оплаты на сайте интернет-магазина, для этого достаточно внести изменения в один модуль.
«ООО «СТМ»», Санкт-Петербург
В реальности добавление новой функции или процесса так или иначе затрагивает остальные, но принцип микросервисной архитектуры позволяет выпускать готовые релизы в разное время и даёт каждой команде возможность работать в собственном ритме. То есть параллельно могут разрабатываться две функциональности, например поиск и способы доставки, при этом изменения в одном могут происходить хоть каждый день, а изменения в другом требуют больше времени — например из-за того, что релиз должен быть синхронизирован с запуском бизнес-процессов. В рамках микросервисного подхода на это уходит примерно одна неделя с выводом в фазу production.
По сути, микросервисы — это слой между существующей ИТ-инфраструктурой и клиентской частью интерфейса. Его можно с успехом применять практически в любой области и для решения самых разнообразных задач. Также при выборе стратегии ИТ-развития компании в пользу полного отказа от «коробочного» подхода, микросервисы могут стать надёжным и эффективным ядром новой digital-платформы для успешного роста бизнеса в 21 веке.
6 главных преимуществ микросервисной архитектуры
- Новое качество масштабируемости. При возникновении соответствующей потребности не нужно масштабировать всю систему, разбирая её до основания, — достаточно внести необходимые изменения только на определённом участке.
- Повышение стабильности. Поскольку микросервисы независимы друг от друга, сбои и дефекты в одном из них никак не влияют на работу остальных, система функционирует с минимальными сбоями и простоями.
- Упрощение. Вместо единого и сверхсложного массива ИТ, компании работают с более управляемой архитектурой, где каждый компонент отвечает за свою функцию.
- Мультиплатформенность. Микросервисы могут работать на любом устройстве, а также в on-premise и облачных средах.
- Повторное использование. Микросервисы могут перепрофилироваться для других целей и задач после начального запуска.
- Возможность использовать разные технологии. Agile-команды в компаниях могут работать как небольшие стартапы, не ограничиваясь одной определённой платформой или технологией благодаря микросервисам. Через микросервисы организации могут объединять различные технологии для создания действительно лучшего из всех возможных решений на настоящий момент, что значительно ускоряет внедрение инноваций.
Трудности внедрения микросервисов
По сравнению с «монолитами» микросервисы открывают следующий уровень гибкости операций через создание новых бизнес-процессов вокруг уже существующих legacy-систем. Именно поэтому сегодня многие нацелены на микросервисную трансформацию — её преимущества слишком очевидны.
Однако существует ряд подводных камней при реализации такого перехода.
Сохранение целостности компании
Главный вызов — не утратить полезные наработки, накопленные данные и опыт прошлых лет, сохранив капитальные инвестиции в ИТ-инфраструктуру прошлого поколения. То есть компания должна ускорить своё развития и «не развалиться» в процессе трансформации к современному подходу.
Большое количество микросервисов
Когда компании необходимо 10–20 микросервисов, их адаптацией и развитием управлять не так сложно. Но если организация требует для своих задач внедрения 100+ микросервисов, появляется ранее не существовавший класс задач. Как избежать дублирования функциональности, сохранить масштабируемость и управляемость, а также не допустить превращения новой архитектуры в такой же монолит, от которого изначально пытались уйти?
Для организаций эти вызовы и их различные формы и складываются в современное IT, когда от подхода «строим то, что позволяет система» делается качественный скачок к «развиваем систему таким образом, чтобы у нас появлялись новые возможности для перестройки бизнеса». Компания, которая осознаёт необходимость адаптации микросервисов, нацеливается не на рост прибыли, трафика и других количественных KPI, а на глубинные изменения, при которых рост KPI — органическое следствие общей трансформации.
Баланс гибкости и хаоса
Третья проблема микросервисов — высокий уровень гибкости при работе над развитием платформы. Это необходимое условие микросервисного подхода, но если его не контролировать, резко возрастает риск развития хаоса в архитектуре системы. Разобраться в принципах устройства такого «хаоса», возникшего в рамках работы по микросервисным проектам, — зачастую отдельный ИТ-проект. Правильнее с самого начала работы ограничить рамки, пусть даже это немного отложит выпуск первой функциональности, чтобы потом не потратить несколько месяцев на демонтаж «окаменелостей» из микросервисов.
Переход к микросервисам в рамках концепции enterprise agility — это также вопрос корпоративной культуры, которая помогает сохранять необходимый баланс свободы и контроля.
Свободное творчество и практический эффект совместимы только при культурных сдвигах в работе компании. Архитектура, процессы, персонал — все необходимые факторы для развития микросервисов должны выстраиваться в комплексе.
Время и результаты
Перевод ИТ-ландшафта организаций на новую архитектуру не происходит за одну ночь. Как раз наоборот, иногда для этого требуется довольно длительное время, в каких-то случаях — целые годы. Мало какие вещи в современном мире настолько же сложны, как современные ИТ-системы, адаптированные к бизнес-моделям компаний, а также конкретные способы их привязки друг к другу. Тем не менее, несмотря на общую трудоёмкость демонтажа legacy-систем, полагаться на «олдскульные» ИТ в эпоху, когда парадигма New IT развивается семимильными шагами, — значит обрекать бизнес на медленную агонию. Отсюда и вытекает потребность в микросервисной архитектуре.
Продвинутые микросервисные архитектуры в их образцовом исполнения представлены сегодня в таких компаниях, как Google, Amazon и Netflix. Так, Amazon вносит изменения в свои продукты каждые 11,6 секунд, а Netflix постоянно проводит выборочные отключения вычислительных узлов для проверки влияния подобных аварий на общее качество продукта, получаемого абонентами.
Очевидно, что более консервативным организациям подобный переход только предстоит осуществить. Они совмещают старую архитектуру и новейшие подходы к развёртыванию приложений, что в терминологии Gartner называется Bimodal IT — что-то вроде переходной фазы, сочетающей элементы legacy и современных IT-систем.
Между тем, в последующие 10–20 лет legacy-модели должны быть полностью заменены на новейшие решения компаниями, которые хотят сохранить свою конкурентоспособность. В этой перспективе микросервисы и монолитные системы могут сосуществовать как привитая ветвь и ствол дерева, на котором ей предстоит прорасти и в будущем заменить собой отмирающую основу. Такой подход позволяет гарантировать, что корневая система останется незатронутой и медленно, но верно, перейдёт от старого владельца (legacy-систем) к новому (микросервисы и парадигма New IT).
Монолитная vs Микросервисная архитектура
Что такое монолитная архитектура?
Монолитное приложение (назовем его монолит) представляет собой приложение, доставляемое через единое развертывание. Таким является приложение, доставленное в виде одной WAR или приложение Node с одной точкой входа.
Пример
Давайте представим классический интернет-магазин. Стандартные модули: UI, бизнес-логика и дата-слой. Возможны способы взаимодействия с сервисом: API REST и веб-интерфейс.
При построении монолита все эти вещи будут управляться внутри одного и того же модуля. Я не написал «один и тот же процесс», так как это было бы неверно для сценариев, в которых несколько экземпляров нашего модуля будут работать для более высоких нагрузок.
Рассмотрите пример на следующем рисунке, где все части находятся в одном и том же модуле развертывания:
Достоинства
Большим преимуществом монолита является то, что его легче реализовать. В монолитной архитектуре вы можете быстро начать реализовывать свою бизнес-логику, вместо того чтобы тратить время на размышления о межпроцессном взаимодействие.
Еще одна вещь — это сквозные (E2E) тесты. В монолитной архитектуре их легче выполнить.
Говоря об операциях, важно сказать, что монолит прост в развертывании и легко масштабируется. Для развертывания вы можете использовать скрипт, загружающий ваш модуль и запускающий приложение. Масштабирование достигается путем размещения Loadbalancer перед несколькими экземплярами вашего приложения. Как вы можете видеть, монолит довольно прост в эксплуатации.
Теперь давайте рассмотрим негативный аспект монолитной архитектуры.
Недостатки
Монолиты, как правило, перерождаются из своего чистого состояния в так называемый «большой шарик грязи». Вкратце это описывается как состояние, возникшее, потому что архитектурные правила были нарушены и со временем компоненты срослись.
Это перерождение замедляет процесс разработки: каждую будущую функцию будет сложнее развивать. Из-за того что компоненты растут вместе, их также необходимо менять вместе. Создание новой функции может означать прикосновение к 5 различным местам: 5 мест, в которых вам нужно написать тесты; 5 мест, которые могут иметь нежелательные побочные эффекты для существующих функций.
Ранее я говорил, что в монолите легко масштабировать. Это действительно так до тех пор, пока он не перерастёт в «большой шарик грязи», как упоминалось ранее. Масштабирование может быть проблематичным, когда только одной части системы требуются дополнительные ресурсы, ведь в монолитной архитектуре вы не можете масштабировать отдельные части вашей системы.
В монолите практически нет изоляции. Проблема или ошибка в модуле может замедлить или разрушить все приложение.
Строительство монолита часто протекает с помощью выбора основы. Отключение или обновление вашего первоначального выбора может быть затруднительным, потому что это должно быть сделано сразу и для всех частей вашей системы.
Что такое микросервисная архитектура?
В микросервисной архитектуре слабо связанные сервисы взаимодействуют друг с другом для выполнения задач, относящихся к их бизнес-возможностям.
Микросервисы в значительной степени получили свое название из-за того, что сервисы здесь меньше, чем в монолитной среде. Тем не менее, микро — о бизнес-возможностях, а не о размере.
По сравнению с монолитом в микросервисах у вас есть несколько единиц развертывания. Каждый сервис развертывается самостоятельно.
Пример
Давайте вновь рассмотрим в качестве примера Интернет-магазин.
Как и раньше, у нас есть: UI, бизнес-логика и дата-слой.
Здесь отличие от монолита состоит в том, что у всех вышеперечисленных есть свой сервис и своя база данных. Они слабо связаны и могут взаимодействовать с различными протоколами (например, REST, gRPC, обмен сообщениями) через свои границы.
На следующем рисунке показан тот же пример, что и раньше, но с разложением на микроуслуги.
Каковы преимущества и недостатки этого варианта?
Достоинства
Микросервисы легче держать модульными. Технически это обеспечивается жесткими границами между отдельными сервисами.
В больших компаниях разные сервисы могут принадлежать разным командам. Услуги могут быть повторно использованы всей компанией. Это также позволяет командам работать над услугами в основном самостоятельно. Нет необходимости координировать развертывание между командами. Развивать весы лучше с увеличением количества команд.
Микросервисы меньше, и благодаря этому их легче понять и проверить.
Меньшие размеры помогают, когда речь идет о времени компиляции, времени запуска и времени, необходимом для выполнения тестов. Все эти факторы влияют на производительность разработчика, так как позволяют затрачивать меньше времени на ожидание на каждом этапе разработки.
Более короткое время запуска и возможность развертывания микросервисов независимо друг от друга действительно выгодны для CI / CD. По сравнению с обычным монолитом он намного плавнее.
Микросервисы не привязаны к технологии, используемой в других сервисах. Значит мы можем использовать лучшие технологии подгонки. Старые сервисы могут быть быстро переписаны для использования новых технологий.
В микросервисах изолируемые разломы лучше по сравнению с монолитным подходом. Хорошо спроектированная распределенная система переживет сбой одного сервиса.
Недостатки
Все звучит довольно хорошо, но есть и недостатки.
Распределенная система имеет свою сложность: в ней вам приходится иметь дело с частичным отказом, более затруднительным взаимодействием при тестировании (тесты E2E), а также с более высокой сложностью при реализации взаимодействия между сервисами.
Транзакции легче проводить в монолите. Решением этой проблемы на микросервисах является Saga Pattern. Хорошее решение, но все же слишком громоздкое для реализации на практике.
Существуют эксплуатационные накладные расходы, а множество микросервисов сложнее в эксплуатации, чем несколько экземпляров сигнального монолита.
Помимо вышеперечисленных сложностей, для микросервисов также может потребоваться больше оборудования, чем для традиционных монолитов. Иногда микросервисы могут превзойти один монолит, если есть его части, которые требуют масштабирования до предела.
Изменения, затрагивающие несколько сервисов, должны координироваться между несколькими командами, а это может быть сложно, если команды еще не имели контактов.
Заключение
Все зависит от вашей организационной структуры. У вас есть 6 команд, которые будут работать над одним продуктом? Микросервисы могут подойти.
У вас есть команда из 3 разработчиков? Вероятно, они будут хорошо строить и поддерживать монолит.
Другими факторами являются скорость изменения и сложность. Высокие темпы изменений и высокая сложность могут быть факторами, которые заставляют выбрать архитектуру микросервиса.
Напротив, когда вы не очень хорошо знакомы с предметной областью, начать с монолита может быть полезно. Просто сделайте себе одолжение и постарайтесь сохранить его модульным. Это облегчит задачу, если вы когда-нибудь решите разделить свой монолит на несколько сервисов.
Записки программиста
Преимущества и недостатки микросервисной архитектуры
Если вкратце, микросервисная архитектура (Micro Service Architecture, MSA), это когда ваше приложение представляет собой много-много небольших (буквально несколько сотен строк кода) сервисов, взаимодействующих между собой путем обмена сообщениями. Это могут быть сообщения Erlang‘а, Cloud Haskell‘я, Akka, или же REST API, Protobuf, Thrift, MessagePack и так далее. Давайте же попытаемся понять, в каких задачах может быть целесообразно использовать такой подход, чем он хорош, и, конечно же, чем он плох.
Но сначала остановимся немного поподробнее на вопросе «что такое MSA».
В действительности, идея не особо нова. Есть такая штука, как SOA (Service-oriented architecture). По всей видимости, все отличие SOA от MSA заключается в размере сервисов. В случае с MSA исходный код каждого отдельного сервиса не должен превышать нескольких сотен строк кода. SOA же такого ограничения вроде бы не накладывает, поэтому в каждом сервисе могут быть десятки или сотни тысяч строк кода. Видимо, MSA — это частный случай SOA.
Идеи, заложенные в MSA, давно знакомы программистам на Erlang. И вправду, редкий gen_server содержит в себе более нескольких сотен строк кода. И общение с внешним миром действительно производится путем обмена сообщениями. Erlang даже позволяет нам обновить код gen_server’а, не повлияв при этом на другие процессы в системе. Однако MSA предполагает, что каждый сервис представляет собой совершенно независимое приложение. Сервисы в системе могут быть написаны на различных языках программирования и общаться между собой, используя различные протоколы. С высокой степенью точности можно сказать, что процессы и сообщения, предлагаемые Erlang’ом — это частный случай MSA.
Наконец, есть такая давно известная и проверенная временем штуковина, как философия UNIX. Она гласит следующее. Пишите программы, которые делают одну вещь и делают ее хорошо. Пишите программы, которые работают вместе. Пишите программы, работающие с текстовыми потоками данных, потому что это универсальный интерфейс. Фактически, MSA, использующий REST, представляет собой философию UNIX, перенесенную на серверсайд.
Чтобы не возникало каши в голове, отметим, что Erlang — это такой прикольный язык программирования, Akka и Cloud Haskell — библиотеки, модель акторов — это математическая модель, MSA — это архитектура. Идея примерно одна и та же, но слова и кое-какие детали меняются, в зависимости от того, с кем и на каком уровне абстракции вы общаетесь.
Чем же так хороша микросервисная архитектура?
- Писать и поддерживать небольшие сервисы всегда проще, чем большие. Чем меньше кода, тем легче уместить его в голове;
- Если вы решили использовать REST API, то получаете все присущие ему преимущества. Подробности можно найти в этой и этой заметках;
- Поскольку каждый микросервис представляет собой отдельный проект, вы можете практически как угодно распределить их между командами разработчиков. Вы можете строить иерархии из сервисов. То есть, некие сервисы будут использованы только парой сервисов, предоставляющих внешний API для других сервисов. Это масштабируемый подход, то есть, над системой могут одновременно трудиться многие десятки программистов. И никаких проблем с разрешением конфликтов или поиском сложных логических ошибок, появляющихся в результате двух коммитов, сделанных разными программистами;
- Если вы что-то помните о бизнес-моделировании и EPC-диаграммах, то можете к своему удивлению обнаружить, что бизнес-процессы хорошо ложатся на MSA;
- Для каждого сервиса можно выбрать язык и библиотеки, подходящие конкретно для решаемой этим сервисом задачи. Если нужна скорость, берем C++, если просто гоняем туда-сюда данные, берем Erlang, если нужна какая-то необычная библиотека, берем Clojure;
- Практически из коробки получаем горизонтально масштабируемый и отказоустойчивый код, да и к тому же с конвейерным параллелизмом. Даже если вы пишите на Python или OCaml. При «монолитном» же подходе часто в целях оптимизации хочется по-быстрому впилить тут кэшик, там кэшек, и в итоге система становится не масштабируемой. Потому что кэши так просто выпилить нельзя, а поддерживать их в актуальном состоянии, когда в системе N копий одного сервиса, не так-то просто. Горизонтальное масштабирование, как известно, приводит к экономии денег, так как система может работать на множестве сравнительно недорогих машин. Более того, под каждый конкретный микросервис можно подобрать железо подходящей конфигурации;
- Если в программе всего лишь несколько сотен строк кода, в ней не так-то просто сделать ошибку. Необходимость юниттестов становится сомнительной, а использовать языки с динамической типизацией уже вроде как и не страшно. Упрощается тестирование, ибо полностью покрыть тестами API одного сервиса не представляет большого труда. Можно с легкостью замокать внешние сервисы. Понятно, что один мок-сервис можно повторно использовать при тестировании других зависящих от него сервисов. Не требуется специальное тестовое окружение, сервис можно разрабатывать прямо у себя на макбуке;
- Никто не говорил, что абсолютно все сервисы нужно обязательно писать самому. Всякие там Graphite, RabbitMQ, Riak, PostgreSQL и MySQL, или даже Nginx, отдающий статику с JavaScript, который ходит в наш REST API, также можно рассматривать, как сервисы, являющиеся частью системы. Хотя, конечно же, в них далеко не пара сотен строк кода;
- Модульность. Захотел сделать апдейт — катишь сервис. Если по метрикам видишь, что что-то не так, откатываешь. В какой-то момент заметили, что в сервис больше никто не ходит — просто выключаем его. Вместо рефакторинга проще выбросить сервис и написать его с нуля. Если где-то в системе крутится ужасный легаси-код, но при этом он работает, пускай себе работает, глаза при этом он никому не мозолит;
- Нетрудно отследить зависимости между сервисами. Если все сервисы зависят друг от друга, наверное, что-то в архитектуре вашей системы не так. Если количество связей не намного превышает количество узлов, значит вы на верном пути. Также нетрудно найти критические пути, единые точки отказа и так далее;
- Не страшно экспериментировать с новыми технологиями. Захотел попробовать новый веб-фреймворк, ORM или, например, протащить в проект Haskell — переписываешь существующий сервис и смотришь, насколько это будет работать. Если не работает, откатываешь к старой версии. Попробуйте так просто взять и перейти с Django на другой фреймворк в «монолитном» проекте;
- Сравнительно нетрудно переписать легаси систему в соответствии с MSA. Ставим перед системой зонтик/прокси. Затем потихоньку выносим компоненты системы в сервисы, а прокси следит за тем, чтобы клиенты ходили туда, куда нужно;
- Даже если ты пилишь тупо сайтик, с MSA чувствуешь себя крутым разработчиком распределенной системы 🙂
Очевидный недостаток всего этого хозяйства заключается в необходимости гонять данные между микросервисами. Если накладные расходы на обмен сообщениями, а также их сериализацию и десериализацию, слишком велики, нужно либо оптимизировать протокол, либо подвинуть взаимодействующие сервисы друг к другу поближе, либо объединить их в один микросервис. Не так-то просто все это админить, хотя, если ваши админы осилили Chef или Ansible, то, скорее всего, особых проблем быть не должно. Очевидно, при использовании MSA следует серьезно отнестись к логированию (вероятно, в отдельный пул сервисов) и мониторингу. Притом те, кто используют MSA, рекомендуют в первую очередь собирать бизнес метрики — количество продаж, результаты А/Б тестирования и так далее. Все это, впрочем, справедливо в отношении любой серьезной системы.
Если ваши микросервисы используют какую-нибудь общую библиотеку, а в этой библиотеке, например, обнаружилась бага, то нужно обновить версию библиотеки во всех сервисах, а потом все их раскатить. Поэтому при использовании MSA общего кода должно быть как можно меньше. Общий код должен быть либо предельно простым, либо меняться крайне редко. Иногда, если сервисы делают похожие вещи, код лучше скопипастить, потому что в будущем эти вещи могут стать не такими уж и похожими. Ну и, конечно же, ни в коем случае не используйте какие-нибудь общие инклудники с объявлениями record’ов, как это порой делают в Erlang.
- Пост Micro Service Architecture в блоге James Hughes;
- Длинный, но преинтереснейший пост о платформах, SOA, Amazon, Microsoft, Facebook и Google;
- Micro Service Architecture, презентация Eduards Sizovs;
- Fred George рассказывает о MSA, Clojure, Kafka и утверждает, что можно катить микросервисы в продакшн каждые 10 минут (каждый прогер — дважды в день). Слабо верится, но звучит интересно. Также из этого доклада вы узнаете о хороших практиках MSA, например, что каждый сервис должен отдавать информацию о своем текущем состоянии;
- Доклад James Lewis под названием Micro Services: Java, the Unix Way. Субъективно послабее, чем у Fred George, но также заслуживает внимания. Вся суть начинается где-то с 21-ой минуты;
Мне что-то не очень верится в идею «несколько сотен строк кода не сервис», даже с учетом кучи готовых фреймворков и библиотек. Вот пара тысяч строк на сервис звучит более реалистично.
Скорее всего, не во всякой задаче можно или нужно использовать микросервисную архитектуру. Но там, где есть такая возможность, как мне кажется, преимущества существенно перевешивают недостатки.
Микросервисы: как определить, подойдут ли они вашему проекту
Микросервисы — популярный подход к разработке, который Netflix и Amazon успешно используют больше трех лет.
Мы заметили, что не всегда выбор микросервисов бывает осознанным. Чтобы микросервисы выбирались сознательно, мы решили разобрать наиболее частые вопросы:
В чем преимущества микросервисов?
Для каких решений лучше выбрать микросервисы?
Что такое микросервисная архитектура
Термин «микросервисы» раскрывает Сэм Ньюмен в книге “Building Microservices”: это небольшие и нацеленные на то, чтобы хорошо справляться только с одной работой, автономные, совместно работающие сервисы.
Сама идея разделять систему на независимые компоненты не нова. Предшественником микросервисной архитектуры является сервис-ориентированная архитектура (SOA), которая также разделяет бизнес-логику на компоненты. По сути, микросервисная архитектура — частный случай SOA c набором более строгих правил.
У микросервисов есть особые свойства, они же преимущества:
- Гетерогенность: возможность построить систему с помощью разных языков программирования и технологий;
- Децентрализованное управление данными: каждый микросервис содержит свой набор данных, доступный другим микросервисам только через соответствующий интерфейс;
- Независимость инфраструктуры: каждый микросервис — независимая единица, поэтому вносить изменения и разворачивать его можно независимо от других;
- Масштабируемость: чтобы увеличить производительность системы, нужно расширить только те сервисы, которые в этом нуждаются.
Микросервисы vs монолит
Микросервисы противопоставляются традиционной монолитной архитектуре. Монолит означает, что компоненты продукта взаимосвязаны и взаимозависимы. Если перестает работать один — все остальные тоже «отваливаются».
Стремительное развитие IT-сферы накладывает новые требования: развитие технологий, меняющиеся потребности конечных пользователей — на все это нужно быстро реагировать. Если в 2005 году можно было разрабатывать продукт несколько лет, сейчас базовую версию нужно выпустить за пару месяцев.
В таких условиях микросервисная архитектура выигрывает у монолита:
- Проще изменить один из микросервисов и сразу внедрить его, чем изменять весь монолит и перезапускать инфраструктуру целиком;
- Новые разработчики легче включаются в работу — для этого им не нужно изучать систему целиком, можно работать только над своей частью;
- Микросервисы не зависят от какой-либо платформы, поэтому внедрять новые технологии проще, чем в монолит.
Недостатки подхода
Не все так идеально. Микросервисы накладывают ограничения на разработку и поддержку продукта:
- Сложность начальной разработки и создания инфраструктуры. Распределенные системы сложнее разрабатывать, т.к. нужно предусмотреть независимость одного микросервиса от сбоя в другом компоненте;
- Разработка распределенных систем накладывает дополнительные расходы на обмен данными между микросервисами: нужно правильно выбрать протоколы общения между компонентами, чтобы взаимодействие было максимально эффективно;
- Для распределенной системы сложно поддерживать строгую согласованность: общие части системы нужно либо складывать в общую библиотеку, но тогда при изменении этой библиотеки нужно будет перезапускать и все зависимые микросервисы, либо хранить общий код в каждом из микросервисов, но такой код идет вразрез с принципом DRY (Don’t repeat yourself), и его сложнее поддерживать;
- Другая структура команды разработки. Команда разбивается на группы, каждая из которых полностью разрабатывает один микросервис. Глава Amazon Джефф Безос предлагает оптимальный размер команды: чтобы их можно было накормить двумя пиццами, т.е. 7-9 человек.
Празднование релиза проекта в IT.Place
Получается, что на ранних стадиях разработки результаты быстрее дает монолитная структура. При дальнейшем развитии такой системы поддерживать ее станет сложнее. Микросервисы требуют большого внимания и квалификации разработчиков. Нужно многое сделать до выпуска первого сервиса: продумать инфраструктуру, разобраться с протоколом передачи данных, настроить конвейеры развертывания и изменить способ мышления в разработке программного обеспечения. С появлением первого готового сервиса новый функционал будет появляться быстрее, чем при монолитной архитектуре.
Сначала — монолит
Мартин Фаулер, один из основоположников идеи микросервисов, предложил объединить оба подхода в один — «Сначала — монолит» (MonolithFirst). Основная идея: «не следует начинать новый проект с микросервисов даже при полной уверенности, что будущее приложение будет достаточно большим, чтобы оправдать такой подход». В монолитном проекте проще наблюдать связность модулей и добавлять новый функционал. Затем система разбивается на несколько частей, и они переделываются в обособленные микросервисы.
Так преодолевается главный недостаток создания микросервисной архитектуры с нуля: не нужно тратить много времени на первоначальное деление системы на компоненты и организацию взаимодействия между ними. Важно выбрать правильный момент для начала разделения на сервисы: слишком рано — и микросервисы не будут наполнены необходимой бизнес-логикой, слишком поздно — границы модулей будут размыты, и разделить на микросервисы будет сложно. Верный признак, что нужно начинать делить — когда стоимость нового функционала становится выше, чем польза от него. Например, если приложению понадобилось подключение к нескольким платежным системам, стоит выделить эту логику в обособленный сервис, чем приспосабливать всю систему под них.
Главный недостаток такого подхода описан в статье Don’t start with a monolith: сложно разрабатывать монолитную структуру, которую впоследствии можно будет безболезненно разделить на компоненты. С переходом на микросервисы изменятся и команда, и процессы разработки. Например, независимая доставка изменений каждого микросервиса на боевой сервер, версионирование компонентов, дробление команды на группы, достаточные для обслуживания каждого микросервиса.
Для каких решений лучше выбрать микросервисы
Обратите внимание на параметры проекта: предметную область, квалификацию команды, сроки релиза, нагруженность проекта, количество внешних систем, с которыми приложение должно общаться. Если на проекте не планируются высокие нагрузки и постоянное добавление взаимодействия с внешними сервисами (платежные системы, банки, внешние хранилища и т.п), лучше выбрать монолит. И наоборот: если система должна работать при любых нагрузках и с большим количеством сервисов, то микросервисная архитектуры обязательна.
На момент написания статьи мы с командой разрабатываем систему управления сетью постаматов. Клиент заказывает посылку в интернет-магазине и забирает ее в удобное время в одном из постаматов — никаких очередей на почте и потерянных посылок. После анализа требований мы выбрали микросервисную архитектуру, т.к одно из условий существования системы — ее постоянное масштабирование: система должна взаимодействовать с платежными системами, банками, агрегаторами посылок и т.п. И когда нам понадобилось интегрировать систему с очередной транспортной компанией, мы поняли, что приняли правильное архитектурное решение: каждый компонент независим, поэтому мы разработали новый микросервис независимо от основной части, не останавливая работу системы.
Рассказ об опыте разработки микросервисной архитектуры будет неполный без упоминания трудностей, с которыми придется столкнуться. Спустя пару месяцев после первого релиза, мы обнаружили проседание производительности в некоторых частях системы. Это произошло из-за того, что несколько микросервисов приняли на себя слишком много бизнес-логики. Отсюда и главный совет: всегда обращайте внимание на то, как логика приложения ложится на компоненты и будьте готовы «перекраивать» эти компоненты для достижения наилучшего результата. Но даже здесь нам удалось исправить ситуацию минимальными затратами: перегруженные микросервисы мы разделили на более мелкие, один из компонентов — прокси запросов в систему — просто переписали с нуля с использованием более быстрых технологий. И самое главное, всю работу мы смогли распараллелить и предоставить пользователям сервиса первые результаты оптимизации уже за несколько часов.
Последствия архитектурных решений будут видны только спустя некоторое время, т.к. решения в начале пути принимаются на основе неполной информации. Но если микросервисная структура выбрана верно, преимуществ от ее использования будет больше, чем недостатков.