Проектирование и микросервисы для самых маленьких
Проектирование системы — очень ответственное мероприятие. Ошибки на этом этапе самые дорогие.
Важная часть обучения любого человека, желающего стать профессионалом — обмен опытом, ведь это позволяет избежать многих проблем. Мне удалось побеседовать на тему проектирования микросервисов со спикером предстоящей конференции DotNext 2016 Moscow Никитой Цукановым и получить ответы на свои вопросы. Если вы ни разу не применяли подход, основанный на микросервисах, рекомендую ознакомиться с этой концепцией построения архитектуры. Под катом информация к размышлению для будущих и настоящих архитекторов.
Никита Цуканов:
… Подумайте над тем, насколько у вас независимы компоненты приложения.… Важно увидеть в своей системе швы, по которым её можно безболезненно разрезать, и оценить пользу от дальнейших манипуляций скальпелем.
О микросервисах в целом и их преимуществах
— Никита, расскажите немного о микросервисах в целом и особенностях микросервисной архитектуры для .NET
— Дать понятие того, что есть микросервис, проще всего в сравнении с классической «монолитной» структурой приложения, к которой все привыкли. В монолитном приложении у нас есть некая единая кодовая база, компилирующаяся в один большой исполняемый файл и его зависимости (иногда их несколько, когда, например, необходимо вынести фоновые задачи из IIS в работающий отдельно Windows-сервис). Главным критерием монолитности является то, что для обновления приложения нам надо взять его исходники, собрать и провести деплой на все сервера, на которых оно должно работать. К таким полным пересборке и деплою приводят даже самые маленькие изменения, неважно, где именно они сделаны. В ряде случаев возникает желание разделить жизненный цикл разработки отдельных частей приложения, разделить зоны ответственности команд. Для выполнения этих задач приложение по сути разделяют на несколько, каждое из которых выполняет свою обособленную от остальных задачу, имеет свой цикл разработки, тестирования и развёртывания. Надо понимать, что общение приложения со своими собственными экземплярами по сети ещё не делает его основанным на микросервисах, оно остаётся монолитным.
— В чем преимущества применения микросервисов в проектировании ПО? Как сильно различаются между собой подход к проектированию программных систем на микросервисах и стандартный подход, основанный на монолитной архитектуре приложения?
— Главным преимуществом микросервисов является более чёткое разделение приложения на компоненты, невозможность сделать в коде лапшу теперь гарантируется не конвенциями и корпоративным стандартом проектирования, а физическим разделением кодовых баз. Если у вас уже всё правильно спроектировано, то подход в целом отличаться будет мало, у вас будут всё те же отвечающие за свою задачу компоненты с легко заменяемыми реализациями, между которыми будут определены контракты вызовов. Скорее всего, из изменений вы увидите только появление прослойки в виде сетевого взаимодействия. Если спроектировано всё неправильно, то микросервисы не сделают магическим образом из плохой архитектуры хорошую.
— Представим, что перед нами стоит задача спроектировать систему. Какие есть индикаторы того, что следует применять архитектуру, основанную на микросервисах?
— Главное — не пытаться разделить неразделимое, не использовать микросервисы ради использования микросервисов. Подумайте над тем, насколько у вас независимы компоненты приложения. У вас наверняка есть кочующий из проекта в проект код, слабо связанный с остальной кодовой базой. Хорошим примером является модуль интеграции с платёжными системами. На вход он должен получить сумму и номер заказа, в ответ выдать URL для перенаправления на оный пользователя, а в дальнейшем прислать сообщение о прохождении платежа. У него есть чётко определённый интерфейс взаимодействия, который прекрасно ложится на REST API, его спокойно может делать сидящая в другом городе команда, которая про ваш основной проект вообще ничего не знает. Можно выделить в микросервис локализацию текстов ошибок, модуль сбора курсов валют (курсы валют вообще избитый пример для всего подряд, что, впрочем, не делает его плохим).
Важно увидеть в своей системе швы, по которым её можно безболезненно разрезать, и оценить пользу от дальнейших манипуляций скальпелем.
— Как такой подход к проектированию влияет на отказоустойчивость и надежность конечной системы?
— С одной стороны, обособленные компоненты становится легче тестировать, поскольку к ним есть чёткий набор требований, а чем меньше кодовая база, тем меньше цена тестирования на единицу функциональности. С другой — сложность вашей системы в целом возрастает, вам нужно тестировать компоненты с разными версиями друг друга, у вас возникают проблемы с деплоем, которых могло бы не быть при монолитной архитектуре.
Главная проблема — размывание ответственности
Какие есть подводные камни при применении архитектуры на микросервисах?
— У нас узкая специализация. Один пришивает карман, один — проймочку, я лично пришиваю пуговицы. К пуговицам претензии есть?
— Нет! Пришиты насмерть, не оторвёшь! Кто сшил костюм? Кто вместо штанов мне рукава пришил? Кто вместо рукавов мне штаны пришпандорил? Кто это сделал?
— Скажите спасибо, что мы к гульфику рукав не пришили.
А.И. Райкин про микросервисы
— Главная проблема, с которой мы столкнулись при применении микросервисов — размывание ответственности, которое грозит переходом к коллективной безответственности. Если что-то всё-таки не работает, становится трудно определить конкретное содержащее ошибку звено, особенно если таких ошибочных звеньев на самом деле несколько, или же проблема вовсе в более высокоуровневой архитектуре.
Разработчики конкретных сервисов начинают валить проблему друг на друга, утверждая, что у них всё нормально, им что-то не так передали и т. п. Ситуация усугубляется тем, что если вы таки соблазнились на обещания возможности делать микросервисы на разных языках программирования, быстрое исправление проблемы зачастую становится невозможным, так как оно потребует участия сразу нескольких разработчиков. Также большой проблемой становится снижение уровня владения кодовой базой в целом конкретными разработчиками, теряется и без того малая взаимозаменяемость, что может больно ударить, если кто-то ушёл в отпуск, заболел или просто занят на какой-то более сложной задаче.
— Какие технологии вы предлагаете использовать для реализации микросервисов? Как и по каким протоколам происходит обмен данными между отдельными микросервисами?
— Поскольку сама идея микросервисов предполагает, что разрабатываться они могут на разных фреймворках и языках программирования, выбор свой следует остановить на максимально простых и переносимых протоколах, инструменты для работы с которыми есть везде. То есть, обычное REST API поверх HTTP для синхронного взаимодействия и система обмена сообщениями вроде RabbitMQ для асинхронного. Соответственно, для реализации на .NET рекомендую использовать WebAPI, RestSharp, EasyNetQ. Для документирования REST API себя хорошо зарекомендовал RAML, но это уже дело вкуса и конкретной команды.
Не применяйте микросервисы ради применения микросервисов
–Подразумевает ли такая архитектура, что все сервисы должны работать асинхронно?
Асинхронность работы чего-либо всегда зависит от конкретных требований и особенностей конкретной задачи. Тот факт, что какая-то логика живёт в соседнем процессе/сервере/датацентре/континенте, этих требований и особенностей не отменяет.
— Бывает ли такое, что дробление системы на микросервисы становится вредным?
— Конечно. Если применять микросервисы ради применения микросервисов из-за того, что, сидя за смузи с другом-хипстером, услышал, что они круты, то возникнет ситуация, когда в обмен на усложнение системы не будет получено никаких преимуществ.
— Как тестировать и отлаживать такую систему?
— Если вы применяете микросервисы там, где это оправдано, то никаких проблем с тестированием и отладкой у вас не может быть в принципе, поскольку каждый сервис имеет строго определённый набор изолированных задач и требований и может быть без проблем протестирован как любое другое обособленное приложение.
— Как и с помощью каких инструментов можно быстро понять, где произошел отказ, ошибка или падение, если работа всей системы вдруг остановилась? Или такого не бывает из-за независимости сервисов друг от друга?
— Вам нужны мониторинг и логирование, причём логирование централизованное, через какой-нибудь logstash, иначе вам придётся метаться по всей инфраструктуре в попытках отследить жизненный цикл операции и точку, в которой всё пошло не так. Ввиду вносимой микросервисами дополнительной сложности, поиск точки отказа в системе в целом будет сложнее, к этому надо быть готовым.
— Архитектура на микросервисах — это новый и современный подход к проектированию или просто хорошо забытое старое?
— Микросервисы — это такой Unix-way, когда есть набор программ, каждая из которых делает что-то одно, а их потом связывают вместе. Только вместо текстовых потоков stdin/stdout у нас теперь REST API и системы обмена сообщениями. Также можно вспомнить давнюю ожесточённую дискуссию о монолитных и микроядрах ОС (на рынке победили в итоге монолитные).
Что еще интересного будет в вашем докладе на конференции DotNext 2016 Moscow?
В своём докладе я буду рассказывать о переработке исходных кодов в финальный продукт, для этого микросервисы обычно не требуются.
Послушать доклад Никиты можно будет 9 декабря в рамках конференции DotNext (регистрация).
Также в программе:
.NET Core: State of the art
Squeezing the Hardware to Make Performance Juice
Интеллектуальные чатботы и когнитивные сервисы
Stack Overflow — It’s all about performance!
Advanced Xamarin.Forms
C++ через C#
Продолжаем говорить про арифметику
ASP.NET SignalR: Why It’s Getting Really Crucial for Web Development
Exceptional Exceptions in .NET
Модификация кода .NET в рантайме
ETW — Monitor Anything, Anytime, Anywhere
End-to-end JIT
Performance tuning Stack Overflow tags
C# Scripting — why and how you can use your C# in places you never thought of before!
Multithreading Deep Dive
Собрать всё, или Знакомимся с Cake (C# Make)
WinDbg Superpowers for .NET Developers
Overview of the new .NET Core and .NET Platform Standard
Какие уязвимости находят в .NET платформе и как не повторить их в своих приложениях
What’s new in C# 7?
И небольшой опрос по теме.