Проектирование системы — очень ответственное мероприятие. Ошибки на этом этапе — самые дорогие.

Важная часть обучения любого человека, желающего стать профессионалом — обмен опытом, ведь это позволяет избежать многих проблем. Мне удалось побеседовать на тему проектирования микросервисов со спикером предстоящей конференции DotNext 2016 Moscow Никитой Цукановым aka kekekeks. Если вы ни разу не применяли подход, основанный на микросервисах, рекомендую ознакомиться с этой концепцией построения архитектуры. Под катом информация к размышлению для будущих и настоящих архитекторов.

Никита Цуканов:

… Подумайте над тем, насколько у вас независимы компоненты приложения.… Важно увидеть в своей системе швы, по которым её можно безболезненно разрезать, и оценить пользу от дальнейших манипуляций скальпелем.


О микросервисах в целом и их преимуществах


– Никита, расскажите немного о микросервисах в целом и особенностях микросервисной архитектуры для .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?

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

Проголосовало 187 человек. Воздержалось 44 человека.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

Поделиться с друзьями
-->

Комментарии (10)


  1. RayAtlas
    24.10.2016 10:10
    +18

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


    1. Denxc
      24.10.2016 10:24

      Расценивайте эту статью как анонс конференции и доклада, где будет желаемая вами конкретика.


    1. ARG89
      24.10.2016 10:42
      +7

      На самом деле замечание совершенно верное, пока готовили статью, на эту же тему вышло несколько подобных интервью… В будущем будем брать более глубокие темы, спасибо за предложение!


    1. greendimka
      24.10.2016 14:18
      +1

      По-моему всё это делается с целью заманить народ на конференцию. Но не в этом суть.
      Микросервисы не есть что-то новое. И микросервисы не есть серебряная пуля. Это инструмент. И как любой инструмент — он должен применяться там, где ему место, а не везде подряд. Автор абсолютно правильно сказал:


      не использовать микросервисы ради использования микросервисов

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


    1. Myrddin
      24.10.2016 16:40

      Типа теперь еще и на дотнете ))
      Правда с таким вендор-локом пока совершенно не интересно.


  1. 23derevo
    24.10.2016 10:59
    +5

    Обидно, что народ мало говорит (может, просто не знает?) об истоках микросервисного подхода. Кажется, надо смотреть на Amazon, на взгляд их CTO на документацию сервисов и т.п. Там были свои причины так делать, свои требования, и в итоге мы имеем тот Amazon, который имеем.

    А у нас получаются какие-то микросервисы в вакууме. Отсюда и ощущение, что все тексты и все мнения экспертов похожи друг на друга.


  1. vassav
    24.10.2016 16:32
    +3

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


    1. 23derevo
      24.10.2016 20:02
      +1

      Тесты же! Тестируете микросервисы — и проблемы с изменениями вам не страшны.


      1. andreycha
        25.10.2016 14:35

        Тесты тестами, но проблема обновлений действительно существует. Впрочем, это скорее не проблема, а плата за преимущества. Ее можно свести к минимуму, но избавиться от нее нельзя.


  1. zenkz
    25.10.2016 01:55
    +5

    Микросервисы, как и любая другая технология имеет свои плюсы и минусы.

    Из плюсов:
    — Модульность
    — Относительная лёгкость замены одного модуля
    — Масштабируемость
    — Тестируемость

    Из минусов:
    — Усложение системы (там где раньше был простой вызов метода — теперь есть целая транспортная подсистема), а значит понижение надёжности
    — Необходимо учитывать и обрабатывать ситуации, когда микросервис недоступен. (И опять же больше кода = меньше надёжность). Для «монолитов» чаще всего есть 2 состояния «всё работает» и «всё упало», для микросервисов статусов можеть быть намного больше и их все нужно обрабатывать.

    Для себя вижу оправданным следующий подход:
    — Постараться выделить обособленные/переиспользуемые подсистемы и реализовывать их сразу в отдельных микросервисах (основной критерий — слабая связанность с основной системой);
    — остальная система проектируется как слоистый/модульный «монолит», обязательно с взаимодействием через интерфейсы, на основании которых легко вынести нужную часть кода в микросервис.
    — когда стало понятно, что какая-то часть системы стала самодостаточной и обособленной — выносим её в микросервис.

    Просто многие сильно буквально понимают микросервисную архитектуру и создают десятки «микросервисов», которые взаимодействуют друг-с-другом используя сложные последовательности комманд и т.д.
    Для меня микросервисы: это когда система отвечает только за то, для чего она сделана, а вспомогательные вещи (например взаимодействие с платёжными системами, отправка уведомлений и т.д.) реализованы в микросервисах.

    Ну и пара организационных моментов:
    — Назначьте архитектора системы (человека, который будет принимать решение о выносе/создании микросервиса и будет бороться с размыванием ответственности);
    — Старайтесь писать сервисы на одном языке программирования и поддерживайте единый стандарт именования, документации и оформления кода.
    — Старайтесь не разделять команду по направлениям (если размер проекта это позволяет сделать). В этом случае можно уменьшить и даже исключить простои разработчиков из-за ожидания реализации сервисов и проблем с отпусками/больничными/увольнениями и т.д.