Как стать автором
Обновить

Монолог про отказоустойчивость микросервисных приложений, или Что может пойти не так?

Уровень сложностиПростой
Время на прочтение19 мин
Количество просмотров7K
Всего голосов 28: ↑28 и ↓0+28
Комментарии15

Комментарии 15

Мне кажется не хватает важного этапа, на который многим сложно решиться: учения. В продакшне, по живому, во время отпуска техдира и ещё кого-то. Яндекс давно писал: https://habr.com/ru/companies/yandex/articles/243033/ Ну и должны быть кризисные планы, написанные инструкции о том что делать когда всё сломалось. Анализ инцидентов с последующим внесение изменений как в код так и в инструкции так и в план учений.

Да, есть еще хаос инжиниринг, как например в Netflix, где Chaos Monkey ломает всякое нужное в неожиданный момент. Мне всегда такое было интересно, но, к сожалению, попробовать не довелось.

Про планы полностью согласен, в Альфе такое есть, как и деление систем по классам критичности, чем он выше, тем больше требований к самим системам так и к disaster recovery.

Анализ инцидентов - само собой, с изменениями в тестах и т.д. А еще я люблю результаты разбора в личную базу знаний и извлеченных уроков вносить, мало ли где еще с таким столкнешься.

В распределенных системах это обычно внешние распределенные кеши, типа Redis или Hazelcast

Ссылку на статистику, плз. Распределённые обычно используются, если памяти на одном сервере не хватает. Для всего остального они мало полезны.

Проблема с балансировщиком

На клиентской стороне сделать балансировщик - религия не позволяет?

Скорее всего за это время уже запущенные контейнеры не смогут обработать запросы, начнут отказывать и выдавать ошибки

ээээ .... а готовность приверить до регистрации инстанса ваша инфраструктура не позволяет? В кубернетисе это как бы из коробки

 Но в долгосрочной перспективе, естественно, мы переписываем микросервис так, чтобы он сам потреблял меньше ресурсов

Ну наконец-то! Хоть что-то вы делаете разумное.

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

Ничего не снижается. Есть такая штука, теория надёжности называется. Чем больше компонентов - тем менее надёжна система. Вы переносите с больной головы на здоровую подменяете одну точку отказа 2-мя точками отказа.

RabbitMQ или Kafka. В целом, эти каналы коммуникации by design более отказоустойчивые, чем REST, использующий HTTP

С чего это вдруг? Вообще-то они используют тот же самый TCP.

Там, где важная изоляция и надежность можно использовать SQL решения, там, где требуется горизонтальное масштабирование — NoSQL базы данных.

Так значит, SQL базы не обеспечивают горизонтального масштабирование, а NoSQL - надёжности? Ну надо же! Век живи - век учись!

Ссылку на статистику, плз. Распределённые обычно используются, если памяти на одном сервере не хватает. Для всего остального они мало полезны.

При использовании локальных кешей в конфигурации с больше чем одним инстансом, мы получаем увлекательное приключении по обеспечению их непротиворечивости. Плюс их надо греть после каждого рестарта сервиса. Уже эти два момента добавляют полезности распределенным кешам. Но, конечно, это не серебряная пуля. В минусах - дополнительные ресурсы и еще одна тока отказа. Хотя второе обычно нивелируется возможностью запустить тот же редис в режиме кластера.

На клиентской стороне сделать балансировщик - религия не позволяет?

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

ээээ .... а готовность приверить до регистрации инстанса ваша инфраструктура не позволяет? В кубернетисе это как бы из коробки

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

Ну наконец-то! Хоть что-то вы делаете разумное.

Спасибо :)

Ничего не снижается. Есть такая штука, теория надёжности называется. Чем больше компонентов - тем менее надёжна система. Вы переносите с больной головы на здоровую подменяете одну точку отказа 2-мя точками отказа.

Согласен, EDD в целом тема довольно холиварная, а системы на его основе сложнее и в разработке и в отладке. Я, конечно, хожу тут по тонкому льду, но при наличии надежной шины, мы перекладываем на нее часть ответственности. Например, если нужно доставить сообщение от A к B, то при недоступности B, при синхронном обмене нужно будет реализовывать повторные отправки и персистенс в A. При наличии шины, A отправит сообщение и забудет про него, а B прочитает его когда вновь станет доступен. Опять же, рецепт не универсальный и со своими подводными камнями, но связность тут явно меньше, как мне кажется.

С чего это вдруг? Вообще-то они используют тот же самый TCP.

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

Так значит, SQL базы не обеспечивают горизонтального масштабирование, а NoSQL - надёжности? Ну надо же! Век живи - век учись!

Каюсь, слишком упростил, тем более в такой теме... Но CAP теорему в любом случае нужно держать в голове, все же SQL и NoSQL относятся к разным классам и обеспечиваю несколько разные характеристики.

Если вместо событийной архитектуры использовать реактивную, то всё сильно упрощается: А записал в локальную базу и забыл, протокол синхронизации гарантирует доставку до В, который реагирует на изменение в своей локальной базе.

А что делать, если для реакции не хватает только той информации, что есть в базе? Допустим, если нужно еще знать пользователя, который внес эти изменения?

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

А что из реального "не так" было самое жоское?

Ну лично мне больше всего запомнился сгоревший БП у сервера на котором монолит хостился, не зря тут картинка с лодкой.. SSH на телефоне и редактирование конфигов в vim'е с помощью экранной клавиатуры с чуть живым мобильным интернетом - это развлечение очень на любителя.

Монолит прекрасно реплицируется для разделения нагрузки и повышения надёжности. Я бы даже сказал, это всегда во все времена было must be как раз на случаи типа сгоревшего БП в 3 ночи.

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

Лично для меня всегда была большая проблема во всех этих микросервисах, особенно имеющих "каждый свою БД" - гарантировать целостность данных в любой момент времени. Даже когда все штатно работает, не говоря уже о тех случаях, когда что-то упало.

P.S. Иногда так хочется все слить в один монолит, у которого только 2 состояния - работает или нет. Эти десятки сервисов, баз, эндпоинтов, которые (конечно же "слабо", но) зависят от остальных. К ним куча метрик, графиков, алертов, скриптов обслуживания и пр.

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

С какой это стати "единственная база" вдруг становится узким горлышком? Может, просто вы не умеете СУБД готовить?

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий