Comments 46
Я нежно люблю монолиты за их скорость, но программный интерфейс между подсистемами внутри монолита нельзя называть сильной стороной этого паттерна
Интересно, не придумал ли кто-то способа энфорсить слабо связанную архитектуру, не заставляя маршалить данные и взаимодействовать по сети?
Понятное дело, что очень ограниченно работает для компонент на разных языках программирования, но там без сериализации данных в любом случае не обойтись.
Придумали. Через ipc.
Интересно, не придумал ли кто-то способа энфорсить слабо связанную архитектуру, не заставляя маршалить данные и взаимодействовать по сети?
Бить монолит на модули и следить за границами.
нельзя например передавать ссылки, на что-то внутренне а только value object. Пакеты это никак не ограничивают.
Код ревью. Микросервисы слабо связанную архитектуру то не обеспечивают. Это просто более явные границы которые люди всё равно нарушают/проводят неправильно. Чем больше мода на них и проще их становится пилить, тем больше людей появляется у которых всё это дело деплоится как единый связанный монолит.
ИМХО проблемы с RESTAPI: его документирования, консистентности и совместимости это другая плоскость и RESTAPI в микросервисы/монолитах имеют одини и теже проблемы.
Разве что в микросервисной архитектуре добавляется необзодимость собирать документацию из нескольких проектов которые могут быть разработаны на разных языках программирования.
К сожалению, нет. Просто в монолите вы можете нарушать контракт более вольготно за счет того, что его легко менять, но соблюдение четких контрактов там работает исключительно на ревью кода.
Стоит так же учесть, что в монолите серьезной проблемой является удерживание архитектурных границ и нерешаемой проблемой скалирование части функционала монолита.
Микросервисы – это «кирпичики», из которых разработчики создают современные приложения.
Как потом деплоится такое приложение?
А то вкупе с многочисленными упоминаниями «общения микросервисов», причём по http, возникает мысль что речь идёт про распределённый монолит взаимодействующий по сети, а не независимые микросервисы.
Но обычно история про deploy отделена от истории про API.
7 бед — один кубернет. И с ним уже 8 бед.
Намекаете на то что мысль выше — верна? Ок, спасибо.
Но обычно история про deploy отделена от истории про API.
Ну, я бы сказал что история про deploy перекликается с историей про обратную совместимость, но вопрос выше у меня возник из-за того что обе последние статьи про API вы плотно перемешиваете с историей про микросервисы.
И утверждения, процитированное в предыдущем комментарии, и:
Де факто есть два способа взаимодействия микросервисов – HTTP Rest и gRPC от компании Google
Показались сомнительными, и как мне показалось, говорят о зависимых друг от друга сервисов(это норма, вопрос лишь в количестве зависимостей).
>>7 бед — один кубернет. И с ним уже 8 бед.
Намекаете на то что мысль выше — верна? Ок, спасибо.
kubernetes как ответ на вопрос «как потом деплоится такое приложение?». под «распределённый монолит взаимодействующий по сети» Вы имеете в виду сильную связность сервисов?
я бы сказал что история про deploy перекликается с историей про обратную совместимость
Безусловно, чтобы обновить API нужно раздеплоить новую версию компонента. Но, Евгений, кажется, я не улавливаю Выше мысль. Развернете?
Вы имеете в виду сильную связность сервисов?
Да. Интересно было бы узнать, независимый ли у микросервисов цикл релизов друг от друга, и сколько сил/времени занимает координация релизов, она ведь всё-равно нужна иногда.
Безусловно, чтобы обновить API нужно раздеплоить новую версию компонента. Но, Евгений, кажется, я не улавливаю Выше мысль. Развернете?
Всё так, наверное не очень корректно было спрашивать именно про деплой в первом коммментарии.
Если происходит поломка обратной совместимости API сервиса, которое используется другими сервисами, нужно править их, а это коммуникации между командами и ожидание обновления от них(=время, деньги, медленнее деливери).
Вы ранее назвали HTTP/gRpc стандартом общения микросервисов, а это значит что общение происходит синхронно(request/response), хотя для поддержания низкой связности всякие event-driven подходы считаются предпочтительнее.
Есть два варианта, как быть с обратной совместимостью апи:
- Поддерживать разные версии АПИ в одном сервисе.
- Поддерживать в продакшне разные версии самих сервисов, а на апи распределять уровнем выше на входе.
Второй вариант, ИМХО, проще, но может быть чреват проблемами безопасности из-за необновляемости, либо же нужно будет поддерживания несколько версий сразу.
Общение не всегда может быть предпочтимо по событийной модели. В частности, в случае, когда скорость ответа достаточно критична. А иногда и просто логически не имеет смысла. Например, у нас был сервис, который получал какие-то данные из эластика и формировал из них некие структуры в API-ответе, которые надо было потом выдать в конечном итоге на фронтенд. Событийная модель здесь ну прям совсем неуместна.
Интересно было бы узнать, независимый ли у микросервисов цикл релизов друг от друга, и сколько сил/времени занимает координация релизов, она ведь всё-равно нужна иногда.
В Acronis сложная модель deploy-я в том смысле, что кроме облака, которым оперируем мы сами, есть еще on-premise deployment, когда наше облако разворачивают customer-ы для своих личных нужд. Поэтому модель «поправили (микро)сервис, залили в прод» у нас не применима. Мы выпускаем целостные релизы Acronis Cyber Cloud где фиксированы версии каждого сервиса
Вы ранее назвали HTTP/gRpc стандартом общения микросервисов, а это значит что общение происходит синхронно(request/response), хотя для поддержания низкой связности всякие event-driven подходы считаются предпочтительнее.
В архитектуре, чисто философски, все компромисс. Иногда ведь и Вы, как архитектор, наверняка отказываетесь от более мощных решений (дающих лучшее масштабирование или производительность) в пользу более понятных решений (дающих более быстрый кодинг, ниже стоимость сопровождения). Cинхронное общение с одной стороны более понятное (простое с точки зрения отладки), с другой стороны более быстрое (все-таки проход через очередь дает много накладных расходов, хотя и добавляет гарантий). Поэтому, как мне кажется, в целом http/gRPC более широко используются чем общение через очереди. Ну и на http можно асинхронное имплементировать (202 и в путь).
Но я согласна с Вами, что event-driven подход имеет свои преимущества
Cинхронное общение с одной стороны более понятное (простое с точки зрения отладки), с другой стороны более быстрое (все-таки проход через очередь дает много накладных расходов, хотя и добавляет гарантий). Поэтому, как мне кажется, в целом http/gRPC более широко используются чем общение через очереди. Ну и на http можно асинхронное имплементировать (202 и в путь).
Так суть как раз в том чтобы не рассматривать http vs queue как две разных реализации транспорта, а делать меньше запросов за данными, получая и сохраняя информацию заранее у себя через всякие Event Notification и Event-Carried State Transfer.
Но у меня такие вопросы потому что я микросервисы рассматриваю как более явные границы и лучшую изоляцию именно для независимой разработки, если разработчиков много и это действительно нужно.
Иначе я не представляю зачем, да и тот же монолит получается.
Маркетинговая политика облачных провайдеров, которая сейчас "прикармливает" клиентов и спикеров на использование кубернетиса а посему на использование микросервисов к сожалению оставляет в тени другие заслуживающие внимания решения например j2ee, wamp. Однако стандарты как показывает опыт побеждают в долгосрочной перспективе.
В общем, здесь можно идти в долгий философский диспут. Я далеко не фанат kubernetes, но, как Вы правильно сказали, стандарты побеждают в долгосрочной перспективе. А из нескольких альтернативных стандартов выживает не всегда самый лучший с технической точки зрения.
Не возникало ли у Вас в процессе мысли о том что проблем было бы меньше если бы использовалось не RESTAPI а более строгая спецификация? А если RESTAPI, то в ее модификации купно с HATEOAS?
А если RESTAPI, то в ее модификации купно с HATEOAS?
Те сервисы Акронис, которые используют мультимедиа контент, следуют рекомендациям HATEOAS. Если у Вас есть позитивный опыт применения HATEOAS в других паттернах, буду рада услышать
Не возникало ли у Вас в процессе мысли о том что проблем было бы меньше если бы использовалось не RESTAPI а более строгая спецификация?
Мысли что-то улучшить рождаются постоянно. Ограничивает обычно время, ресурсы и здравый смысл про лучшее враг хорошего. Но давайте обсудим про более строгие спецификации. Вы имеете в виду GraphQL или что-то другое? И какие плюсы Вы сами в них видите?
GraphQL — да получаем документацию тождественную коду по крайней мере по входным и выходным параметрам и гибкость. Отрицательные моменты — обработка ошибок и проблема SELECT N + 1
Старый добрый SOAP — его правильно редко используют так как сложно. Все дело в том что без VisualStudio генерировать сигнатуры сервисов очень сложно — практически невозможно.
Но не только это. Например WAMP-протокол, JSON-RPC, JSON-API и oData (последние два собственно RESTAPI с попыткой внести систематизацию в формирование запросов)
Не кажется ли вам, что микросервисы через REST api жестко связаны? Почему не использованы очереди вроде Rabbit?
На rabbit можно получить ту же связанность, только ещё и не очевидную.
Тестирование аннотации против имплементации. Для этого мы генерируем из аннотации (RAML/swagger) клиента, который бомбит сервис запросами. Если ответы будут соответствовать аннотации, а сам сервис не будет падать, значит все хорошо.
Зависит от требований в проекте, но обычно тестирования позитивных сценариев недостаточно.
Остановимся подробнее на тестировании. Подобная полностью автоматическая генерация запросов – сложная задача.
Попробуйте schemathesis. Он генерирует тесткейсы из схемы, проверяет и валидные и невалидные данные, коды возврата вроде тоже проверяет.
проверяет и валидные и невалидные данные
На данный момент в Schemathesis сгенерированные данные соответствуют схеме (если нет, то стоит завести баг репорт), но возможны ситуации когда приложение может посчитать их невалидными, например из-за дополнительных проверок которые не укладываются в саму схему и реализованы вручную в приложении.
Т.е. то что они расцениваются приложением как невалидные это больше особенность реализации конкретного приложения и его схемы чем намеренное поведение со стороны Schemathesis.
Тем не менее генерация невалидных данных у нас в плане на ближайшие пару месяцев
Микросервисы: как соблюсти контракт