Независимость микросервисов

Микросервисная архитектура в настоящее время очень популярна. Много кто ее использует, хотя и не всегда на все 100%. Но для успешного применения такого подхода, каждый из микросервисов должен:

  • независимо развиваться (эволюционировать);

  • независимо тестироваться;

  • независимо развертываться.

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

Независимое развитие

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

Например, если говорить о REST, то есть миллион статей об эволюции API, в которых рассказывается об обновлении API без влияния на клиентов.

А если вы используете очереди сообщений (например, Kafka), то обратите внимание на Avro и не начинайте сразу с JSON. Avro поддерживает эволюцию схемы и совместимость, что экономит много времени в будущем.

Проприетарные протоколы остаются на вашей совести. Вероятно, вам придется изобретать велосипед.

Независимое тестирование

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

Я рекомендую познакомиться со Spring Cloud Contract WireMock и Spring REST Docs, которые позволят вам:

  • писать документацию на основе тестов;

  • создавать заглушки (стабы) для вашего сервиса;

  • использовать созданную заглушку в тестах других микросервисов для имитации обращений к сервису.

Пример использования Spring Cloud Contract:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = MOCK)
@AutoConfigureMockMvc
@AutoConfigureStubRunner(stubsMode = LOCAL, ids = "com.github.wirtsleg:my-service-stub:+:stubs:8090")
public abstract class AbstractIntegrationTest {
    ...
}

Таким образом, у вас будет меньше беспокойства о том, как зависимые сервисы взаимодействуют в реальности, потому что вы используете стабы.

Независимое развертывание

Не все могут себе позволить остановку сервиса при обновлении. Но это неизбежно, если есть циклические зависимости (новому сервису A нужен новый B, новому B нужен новый C, новому C нужен новый A). И я уверен, что ни у кого нет желания координировать свои действия с другими командами для релиза новой версии своего микросервиса. О том, как решить эту проблему, мы говорили ранее в разделе о независимом развитии. Но есть еще один момент: сервис должен уживаться со своей предыдущей версией.

Вы, вероятно, слышали термины «сине-зеленое развертывание» (Blue-Green deployment) и «канареечное развертывание» (Canary deployment). Эти подходы предполагают, что новая и старая версии будут сосуществовать какое-то время. А это влечет за собой использование одной и той же базы данных, распределенного кэша и т.д.

Нам нужно поддерживать совместимость с одной предыдущей версией.

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

  1. Добавить новое поле в версии 2 и поддерживать оба поля.

  2. Начать использовать только новое поле в версии 3.

  3. Удалить старое поле в версии 4.

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

Аналогичный подход применяется к распределенному кешу и NoSQL-базам данных.

Заключение

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


Материал подготовлен в рамках курса «Microservice Architecture». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

Источник 📢