Добавить в корзинуПозвонить
Найти в Дзене

Инструменты Techlead Crew

Прошедший выпуск Podlodka Techlead Crew был посвящен межсервисному взаимодействию. Как и всегда, были и знакомые вещи, и не очень. В конечном счете, невозможно знать и помнить обо всём. Вот и я выписал себе очередной набор инструментов, которые показались мне крайне интересными. Чем и спешу поделиться. Продолжаю наблюдать популяризацию идеологии Contract First. С ростом компании растет количество сервисов и продуктов, что неминуемо приводит к необходимости их интеграции и согласования работ между командами разработки. Идеология Contract First — один из инструментов для решения этих проблем, масштабирования компании и процессов. Тема абсолютно не новая, но с популяризацией микросервисов и изобилием протоколов и технологий межсервисного взаимодействия вновь начала набирать популярность. Взяв курс на Contract First, очень важен вопрос выбора инструментов, поскольку они должны унифицировать процесс, контролировать его и ускорять. Иначе говоря, хотелось бы иметь какой-то стандарт или общий
Оглавление

Прошедший выпуск Podlodka Techlead Crew был посвящен межсервисному взаимодействию. Как и всегда, были и знакомые вещи, и не очень. В конечном счете, невозможно знать и помнить обо всём. Вот и я выписал себе очередной набор инструментов, которые показались мне крайне интересными. Чем и спешу поделиться.

Contract First

Продолжаю наблюдать популяризацию идеологии Contract First. С ростом компании растет количество сервисов и продуктов, что неминуемо приводит к необходимости их интеграции и согласования работ между командами разработки. Идеология Contract First — один из инструментов для решения этих проблем, масштабирования компании и процессов. Тема абсолютно не новая, но с популяризацией микросервисов и изобилием протоколов и технологий межсервисного взаимодействия вновь начала набирать популярность.

Взяв курс на Contract First, очень важен вопрос выбора инструментов, поскольку они должны унифицировать процесс, контролировать его и ускорять. Иначе говоря, хотелось бы иметь какой-то стандарт или общий подход к описанию API (хотя бы на уровне компании), возможность верифицировать спецификации (делать ревью, архитектурный контроль, тестирование контрактов) и создавать их максимально быстро и удобно.

TypeSpec
Инструмент от Microsoft для ускорения описания API-спецификаций. Может быть установлен в виде плагина к VSCode (требует установки NodeJS). Спецификация определяется в текстовом файле с расширением `.tsp` и записывается на интуитивно-понятном языке TypeSpec (подмножество TypeScript). Спецификацию можно экспортировать в целевой формат (OpenAPI, JSON Schema, Protobuf), клиентский код или заглушку для реализации сервера (JavaScript, Java, C#). Есть возможность создать свой собственный конвертер. Проект с открытым исходным кодом и активно развивается под лицензией MIT.

Файлы TypeSpec можно положить в Git и получить все преимущества версионирования, контроля изменений, тестирования и т.п. Всё точно так же, как и при написании кода.

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

AsyncAPI
Спецификация для описания асинхронного API и набор инструментов для генерации документации и кода. Спецификация определяется в yaml-формате (есть плагин для VSCode) с достаточно интуитивным DSL. Проект с открытым исходным кодом, который развивается под лицензией Apache-2.0 не менее активно, чем TypeSpec.

Разработка и развитие API требует контроля обратной совместимости. Любые изменения в API должны подвергаться жесточайшему контролю. Помочь в этом может проект OpenAPI-diff.

OpenAPI-diff
Утилита для сравнения двух спецификаций OpenAPI (v3.x), подпроект OpenAPITools. Результат сравнения может быть представлен в формате HTML, Markdown, Asciidoc или JSON. Имеет Java-библиотеку, используя которую можно написать автоматический тест для проверки несовместимых изменений. Проект с открытым исходным кодом и активно развивается под лицензией Apache-2.0.

Я затронул тему тестирования контрактов, которую подробно описывает Крис Ричардсон (см. Consumer-driven contract test, Consumer-side contract test, Consumer-Driven Contracts). Насколько применим этот подход в реальной практике в сочетании с вышеописанным инструментарием. В частности, можно ли интегрировать эти инструменты и Spring Cloud Contract.

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

Если вкратце, то подобную практику использует меньшинство, поскольку формат спецификаций и контрактов очень разный, что обязывает разработчиков спецификаций дополнительно описывать контракты их использования. Честно говоря, аргументация больше похожа на отговорку, но соглашусь, что подобную практику внедрить очень непросто. Однако, если кого-то интересует тема тестирования контрактов, то рекомендую обратить внимание и на проект Pact (спасибо ребятам из чата за эту ссылку).

Pact
Спецификация контрактов (DSL), хранилище контрактов и набор инструментов для тестирования контрактов. Имеет поддержку нескольких платформ и языков (JS, JVM, .NET, Go, Python и т.п.). Проект с открытым исходным кодом и активно развивается под лицензией MIT.

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

Implementation

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

Temporal
Сервер исполнения бизнес-процессов. Бизнес-процесс задается декларативно на интуитивно понятном DSL с использованием клиентской библиотеки (Java, C#, Go и др.). Бизнес-процессы исполняются распределённо, гарантируется согласованность состояния, масштабируемость и отказоустойчивость. В качестве хранилища состояний используется Apache Cassandra, но можно использовать и другие базы, в частности PostgreSQL и MySQL. Проект с открытым исходным кодом и активно развивается под лицензией MIT.

Всё выглядит так, что Temporal позволяет достаточно быстро добавить Saga в существующий проект, особенно если он написан без использования таких структурообразующих фреймворков, как Spring.

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

Centrifugo
Сервер для организации push-уведомлений. Берет на себя множество проблем, которые приходится решать при реализации сервиса уведомлений. Centrifugo встраивается в архитектуру проекта как простой и самодостаточный PUB/SUB сервис. Уведомляемая сторона может взаимодействовать с Centrifugo через наиболее предпочтительный протокол (WebSocket, SSE, gRPC и т.п.). Бэк взаимодействует с Centrifugo через HTTP API или клиентскую библиотеку. Проект с открытым исходным кодом и активно развивается под лицензией Apache-2.0.

Observability

Было очень много сказано про техники обеспечения прочности и устойчивости. Два ярких момента, на которые я обратил внимание.

  1. Крупные компании стараются перекладывать всё больше ответственности с кода на инфраструктуру. Например, выполнение некоторых повторов (Retry) можно возложить на инфраструктуру. Однако на этом уровне имеет смысл повторять только HTTP 5xx.
  2. Распределенная трассировка на базе OpenTelemetry — это неотъемлемая часть современного приложения.

При этом было отмечено, что очень важно не маскировать бизнес-ошибки за кодами HTTP 2xx (например, "HTTP 200 Недостаточно средств"). Это создает серьезные проблемы при сборе статистики о работе системы на уровне инфраструктуры.

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

***

P.s. Если вам интересна данная тематика, присоединяйтесь к моей новостной ленте в Telegram или здесь. Буду рад поделиться опытом. ;-)