Чистая архитектура и микросервисы

Боюсь, что этот текст выльется в достаточно большое количество букв. Но пишу сюда я тексты нечасто, так что может кто-нибудь его и осилит. Тем более, что использование микросервисов уже достаточно долго сопровождается вопросом: зачем мы это делаем. Несмотря на обилие вариантов ответов (например, отличный обзор Nate Schutta (+Matt Stine) Should that be a Microservice? Keep These Six Factors in Mind), вопрос этот задается снова и снова.

«Во многих отношениях микросервисы — это зомби-архитектура. Еще один штамм интеллектуальной заразы, которая просто отказывается умирать. теперь в виде микросервисов и бессерверных технологий» (Дэвид Хайнемайер Ханссон).

После недавнего сообщения в блоге AWS о том, что они отказались от микросервисов и вернулись к монолиту, старая война монолита против микросервисов возобновилась.

Какова ваша позиция по этому поводу? Вы — команда микросервисов или команда-монолит? Что, если бы я сказал вам, что это различие было своего рода фантазией и что люди спорят из-за фикции: микросервисы против монолита — это лишь одна часть более широкой истории.

Статья из AWS была воспринята как свидетельство того, что компания (как давний сторонник микросервисов) отказалась от микросервисов и вернулась к монолиту.

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

Но я хотел бы подчеркнуть, что это не имеет особого значения. Это всего лишь одна команда AWS, признающая, что их первая попытка создать архитектуру не увенчалась успехом (со временем), поэтому они попробовали другую архитектуру, и она сработала лучше. Но что с того? Судя по тому, что я видел за свою карьеру, это обычный способ хорошей разработки программного обеспечения.

Мы все хотим сосредоточиться на самом важном; делаем правильные вещи для наших клиентов. Принятие чьей-либо стороны в дебатах о микросервисах и монолите мешает этому. Иногда нам нужны микросервисы. Иногда нам нужен монолит. (Я еще не уверен, что мне когда-нибудь понадобится FaaS, но я сохраняю непредвзятость). Большую часть времени нам лучше находиться где-то между этими крайностями.

У меня есть свой вариант ответа.

Если говорить просто, идея заключается в переносе идей "Чистой архитектуры" Роберта С. Мартина (дядюшки Боба) из мира монолитных приложений в пространство распределенных архитектур.

 Цитата из его книги "Чистая архитектура. Искусство разработки программного обеспечения"

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

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

Идея номер раз: Парадигма программирования – это набор ограничений. Дядя Боб выделяет три парадигмы и сомневается, что когда-либо появится четвертая. Структурное программирование Дейкстры запрещает непосредственную передачу управления по метке, функциональное программирование – переопределение переменных, а вот объектно-ориентированное … — не очень понятно, что оно запрещает. И здесь история номер один. Простыми примерами на языке С Боб Мартин покушается на нашу уверенность в том, что ООП – это инкапсуляция, наследование и полиморфизм. Даже если вы не знаете С, то поймете примеры — как реализовывали инкапсуляцию и наследование до появления С++. Я это даже помню. Сам так делал. Явных примеров полиморфизма непосредственно в С нет, но их легко найти в структуре FILE из stdio.h. Но тогда зачем же появился язык C++, а потом и Java заменив такие простые механизмы инкапсуляции и наследования из C? Дядя Боб говорит, что для того, чтоб предоставить простой способ реализации структуры плагинов посредством инвертирования зависимостей.

Идея номер два: Работа архитектора программного обеспечения заключается в том, чтоб произвести функциональную декомпозицию (выделить модули) и определить те из них, что целесообразно сделать заменяемыми, то есть плагинами. Для этих модулей необходимо придумать более-менее стабильные (а значит абстрактные) интерфейсы от которых будут зависеть и вызывающие и вызываемые модули. Собственно говоря — всё!

Безусловно я пропустил множество отличных историй из этой книжки. О том, как «неудача» Дейкстры в деле доказательства правильности программ подарила нам такую деятельность как тестирование ПО. Историю о линкёрах и загрузчиках, повлиявшую на весь ход развития информационных технологий. Знаменитую картинку то ли с луковой, то ли с шестигранной архитектурой. Историю о том, почему выделение акторов и юзкейсов не только задача аналитика и как это влияет на архитектуру приложения. И даже недостающую главу, написанную Саймоном Брауном. Интересно, почитайте, а мы вернемся к микросервисам.

Реализация модуля в виде отдельного сервиса принципиально ничего не меняет. Мы преследуем ту же самую цель – сделать заменяемой реализацию части функций нашего приложения. Точно так же где-то внутри вызывающей микросервис системы должен быть интерфейс, задействованный в ходе исполнения сценария. А вот реализация этих функций уезжает в микросервис. Отличия от реализации подхода дядюшки Боба не столь велики. Во-первых, мы должны подумать о поведении системы при недоступности такого микросервиса. Код нужной нам функции исполняется вне нашего процесса. Он может не запуститься, не завершиться или же запросы или ответы в сети потеряются. Во-вторых, нам незачем использовать RPC. Взаимодействие может быть представлено в виде событий, команд и запросов и быть синхронным (преимущественно для запросов) или же асинхронным. В-третьих, локальные ссылки(указатели) при передаче параметров придется поменять на URL; но передача параметров aka по ссылке или же по значению, вообще говоря, остается. DDD – в помощь. Пожалуй, все. Ничего не забыл.

Но самое интересное в этой конструкции — это вопрос: а где живут интерфейсы? Напиши Боб Мартин свою книгу несколькими годами раньше, ответ был бы однозначным. Отвечая на мой вопрос, мегавендоры и консультанты дружно бы скандировали бы: ESB! ESB! ESB… Как вам такая идея? Виртуализация интерфейсов, все дела! Но в нашем времени ESB уже нет. Можно, конечно, попробовать засунуть их в API Gateway, но мы так делать не будем. В нашем времени точкой притяжения всего нужного и полезного функционала являются sidecars – контейнеры, развертываемые с основным процессом на одном узле и помогающие ему решать те или иные задачи, например, задачу service discovery, решаемую при помощи service mesh и пр. Если мы заглянем в книгу Брендана Бёрнса "Распределенные системы". Паттерны проектирования, ну или в другую похожу книжку, то обнаружим там паттерны Амбасадор и Адаптер. Ничего не напоминает? Контейнер Амбасадор, например, вызывается основной программой(локально), чтоб обратиться к некоторой внешней функции. Где эта функция расположена и как реализована мы не знаем. Амбасадор знает. Адаптер, наоборот – помогает внешней системе собрать с нас данные, например, для мониторинга. Сами мы эти API вызывать не умеем и данные никуда не передаем. А вот адаптер нам с этим поможет.

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

С тех пор, как они начали публиковаться в 2006 году, они были свидетелем и сообщали о различных тенденциях в разработке программного обеспечения, которые прошли путь от стадии новатора до широкого внедрения. InfoQ был одним из первых сайтов, сообщивших о движении Agile, а затем последовали Cloud, Containers, DevOps и Microservices.

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

В 2022 году InfoQ уточняет свое видение, публикуя прогноз на перспективу до 2025 года.

Наверное, самое толковое описание применяемой в InfoQ модели дано в книге Джеффри Мура «Преодоление пропасти», хотя сама теория Diffusion of innovations появилась раньше и была популяризована американским социологом Эвереттом Роджерсом еще в 1962 году. Однако у Мура есть ряд важных моментов, на которые часто не обращают внимание. И это не только «пропасть» между ранними последователями (энтузиасты) и ранним большинством (прагматики). В не меньшей степени следует понимать, что представители этих групп – очень разные люди. И от той или иной технологии они ожидают довольно разных вещей.

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

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

Сегодня ситуация изменилась. За последнее время я получил сразу несколько вопросов относительно влияния микросервисного подхода на традиционную корпоративную архитектуру. Не только на системы дистанционного обслуживания, но и на автоматизацию бизнес-процессов, реализуемую посредством BPMS и даже традиционных «коробочных» приложений.  Возможно, задел мой тезис о том, что старой сервисной архитектуре SOA+BPM нет места в новой реальности и разработчики BPM-решений, по крайней мере такие передовые как Camunda, пытаются это осмыслить.

Такое развитие событий довольно логично, как и изменения характера вопросов относительно микросервисов, с вопросов типа «Как?» на вопросы категории «Зачем?». В общем микросервисы, действительно переехали в новую целевую аудиторию.

Чем это грозит разработчикам? Да, в общем, мало чем хорошим. Если на прежних стадиях проникновения технологии можно было с умным видом предлагать микросервисы своим заказчикам, то теперь заказчики перехватывают инициативу. И требовать они будут не микросервисную архитектуру, а масшабируемость, автоматическое восстановление, технологическую независимость и… сокращение сроков внесения изменений, конечно, то есть свой горячо любимый time2marketСтановится решительно непонятно, как использовать старые айтишные отмазки. Вот раньше, когда заказчик просил провести изменение, которое нам почему-то, ну вот совсем не нравится, что мы говорили? Мы говорили, что так делать нельзя, потому что такое изменение порушит текущий функционал. Ну, или что сделать его нам не позволяют ограничения в технологии: мол java у нас не той версии или СУБД слишком реляционная. Сейчас грамотный заказчик резонно заметит: ну, вы не трогайте старый функционал, запилите мне новую фичу в виде отдельного микросервиса, на подходящем технологическом стеке. Системным администраторам не сильно легче. Раньше было как: не хочешь развертывать компонент – не развертываешь. Change advisory board не утвердил, нагрузочное тестирование не выполнено, руководство администратора не согласовано… А сейчас развертыванием занимаются роботы, а безопасность (не информационную) остальных компонентов можно и механизмами типа circuit breaker обеспечить. Одним словом, беда с этими грамотными заказчиками. Зря мы, конечно, там сильно про микросервисы раструбили. Надо бы пойти, какую-нибудь ругательную заметку написать.

На этом всё. Мы перенесли архитектурные практики монолитных систем на распределенные. Расширили спектр ответов на вопрос зачем из первой ссылки этого текста некоторым архитектурным соображением: чтоб как можно дольше иметь как можно больше вариантов. Уверен, что для ряда читателей эти рассуждения покажутся банальными; а для кого-то — полезными.