Микросервисная архитектура в настоящее время очень популярна. Много кто ее использует, хотя и не всегда на все 100%. Но для успешного применения такого подхода, каждый из микросервисов должен: независимо развиваться (эволюционировать);  независимо тестироваться; независимо развертываться. Реальная польза от микросервисов будет при соблюдении всех этих условий. Иначе развертывание новых версий будет требовать координации с другими командами, каскадных изменений всех зависимых сервисов и молитв о том, чтобы все изменения прошли успешно. Каскадный откат изменений может стать серьезным приключением. Приложения со временем эволюционируют. Это неизбежный процесс: бизнес не может заранее предугадать всю необходимую функциональность, а разработчики не могут реализовать все за неделю. Например, если говорить о REST, то есть миллион статей об эволюции API, в которых рассказывается об обновлении API без влияния на клиентов. А если вы используете очереди сообщений (например, Kafka), то обратите внимание на Avro и не начинайте сразу с JSON. Avro поддерживает эволюцию схемы и совместимость, что экономит много времени в будущем. Проприетарные протоколы остаются на вашей совести. Вероятно, вам придется изобретать велосипед. На словах с тестированием обычно все просто, но на деле обработка одного запроса требует обращения к различным сервисам, которые, в свою очередь, зависят от других сервисов. И тестирование перестает быть таким уж независимым. Я рекомендую познакомиться со Spring Cloud Contract WireMock и Spring REST Docs, которые позволят вам: писать документацию на основе тестов; создавать заглушки (стабы) для вашего сервиса; использовать созданную заглушку в тестах других микросервисов для имитации обращений к сервису. Пример использования Spring Cloud Contract: Таким образом, у вас будет меньше беспокойства о том, как зависимые сервисы взаимодействуют в реальности, потому что вы используете стабы. Не все могут себе позволить остановку сервиса при обновлении. Но это неизбежно, если есть циклические зависимости (новому сервису A нужен новый B, новому B нужен новый C, новому C нужен новый A). И я уверен, что ни у кого нет желания координировать свои действия с другими командами для релиза новой версии своего микросервиса. О том, как решить эту проблему, мы говорили ранее в разделе о независимом развитии. Но есть еще один момент: сервис должен уживаться со своей предыдущей версией. Вы, вероятно, слышали термины "сине-зеленое развертывание" (Blue-Green deployment) и "канареечное развертывание" (Canary deployment). Эти подходы предполагают, что новая и старая версии будут сосуществовать какое-то время. А это влечет за собой использование одной и той же базы данных, распределенного кэша и т.д. Нам нужно поддерживать совместимость с одной предыдущей версией. При использовании реляционных баз данных, новая версия, скорее всего, приведет к некоторым миграциям в базе данных. Таким образом, если вам нужно изменить поле в версии 1, то лучше сделать это в три этапа: Добавить  новое поле в версии 2 и поддерживать оба поля. Начать использовать только новое поле в версии 3. Удалить старое поле в версии 4. Таким образом, если с новой версией пойдет что-то не так, то предыдущая версия будет продолжать работать нормально, и вам не нужно останавливать сервис и восстанавливать базу данных. Аналогичный подход применяется к распределенному кешу и NoSQL-базам данных. Это все требует усилий. Одновременная поддержка нескольких версий API, подготовка тестовых заглушек (особенно в первый раз), изменение структуры данных в несколько шагов — все это занимает время. В результате на релиз может уйти больше времени. Но эта дополнительная работа необходима, чтобы в полной мере использовать преимущества микросервисной архитектуры. Материал подготовлен нашим экспертом - Александром Коженковым и опубликован в преддверии старта курса «Microservice Architecture». Если вам интересно узнать подробнее о формате обучения и программе, познакомиться с преподавателем курса — приглашаем на день открытых дверей онлайн. Регистрация здесь. Переводчик, редактор