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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Микросервисная архитектура в настоящее время очень популярна. Много кто ее использует, хотя и не всегда на все 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». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь.

Источник: https://habr.com/ru/company/otus/blog/575518/


Интересные статьи

Интересные статьи

На конференции Java Meeting Point Андрей Перепелкин из экосистемы недвижимости «Метр квадратный» расскажет, как организовать разработку микросервисов, чтобы сделать их ма...
Оркестрация микросервисов помогает выстраивать сложные процессы в продуктах. Чтобы не приходилось прописывать эту механику руками, разработчики могут воспользоваться гото...
Здравствуй, NickName! Если ты программист и работаешь с микросервисной архитектурой, то представь, что тебе нужно настроить взаимодействие твоего сервиса А с каким-то новым и ещё ...
«Битрикс» — кошмар на костылях. Эта популярная характеристика системы среди разработчиков и продвиженцев ныне утратила свою актуальность.
Одной из «киллер-фич» 12й версии Битрикса была объявлена возможность отдавать статические файлы из CDN, тем самым увеличивая скорость работы сайта. Попробуем оценить практический выигрыш от использова...