Pull to refresh

Тесты в продакшне: платформа автоматизации хаоса в Netflix

Reading time9 min
Views4.8K
Original author: Nora Jones


Наш июньский митап Test in Production был посвящён хаос-инжинирингу (chaos engineering). Ведущий инженер-программист Нора Джонс начала с того, как Netflix проводит тесты в продакшне.

«Хаос-инжиниринг… это эксперименты в продакшне для нахождения уязвимостей в системе прежде, чем из-за них сервис станет непригодным для клиентов. В Netflix мы проводим их с помощью инструмента под названием ChAP...[он] отлавливает уязвимости и позволяет внедрять сбои в сервисы и продакшн. Эти сбои подтверждают допущения о данных услугах, прежде чем приведут к полномасштабным отключениям».

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


Расшифровка


Очень рада сегодня здесь присутствовать.

Netflix активно использует тесты в продакшне. Мы делаем их с помощью хаос-инжиниринга, а недавно переименовали нашу команду в Resiliance Engineering [устойчивая разработка], потому что хаос-инжиниринг — одно из средств для достижения общей устойчивости. Об этом я сегодня и собираюсь поговорить.

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

В первую очередь следует позаботиться о безопасности и мониторинге, иначе вы не сможете развернуть нормальные тесты в продакшне. Такие тесты могут пугать: если они пугают, следует прислушаться к этому голосу и выяснить, почему. Может, потому что у вас нет хорошей системы безопасности. Или потому что нет хорошего мониторинга. В своих инструментах мы действительно заботимся об этих вещах.

Если сформулировать хаос-инжиниринг одним предложением, то это дисциплина экспериментов в продакшне для нахождения уязвимостей в системе прежде, чем из-за них сервис станет непригодным для клиентов. В Netflix мы проводим их с помощью инструмента под названием ChAP, что означает Chaos Automation Platform (платформа автоматизации хаоса). ChAP отлавливает уязвимости и позволяет пользователям внедрять сбои в сервисы и продакшн. Эти сбои подтверждают допущения пользователей о данных услугах, прежде чем приведут к полномасштабным отключениям.

Я расскажу, как платформа работает на высоком уровне. Это гипотетический набор зависимостей микросервисов. Есть некий прокси. Он отправляет запрос в сервис A, который потом веерно расходится по сервисам B, C и D, и есть ещё уровень сохраняемости. Служба D обращается к «Кассандре», а затем служба B обращается к кэшу.

Я забегаю вперёд и сжато всё излагаю, потому что дальше начинается суть. Мы хотим убедиться, что служба D устойчива к сбою кэша. Пользователь входит в интерфейс ChAP и выбирает сервис D как сервис, который наблюдает сбои в кэше и сервис для сбоя. ChAP в реальности клонирует сервис B на две копии. Мы используем их для контроля в экспериментальных кластерах: в каком-то роде они работают как A/B-тесты или canary-тесты. Эти реплики намного меньше по размеру, чем сервис B. Мы направляем в эти кластеры только очень, очень маленький процент клиентов, потому что, очевидно, не хотим полномасштабного сбоя. Мы рассчитываем этот процент на основе текущего количества пользователей, использующих сервис в данный момент.

Затем ChAP даёт указание системе внедрения сбоев пометить запросы, которые соответствуют нашим критериям. Это делается путём добавления информации в заголовки запросов. Создаётся два набора тегов. В первом наборе инструкции по сбою и маршрутизации на canary-реплику, а во втором — только инструкции по маршрутизации к элементу мониторинга.

Когда клиент RPC и сервис А получают инструкции, необходимые для маршрутизации запроса, то фактически направляют трафик в кластер мониторинга или экспериментальный кластер. Затем система внедрения сбоя на уровне RPC экспериментального кластера видит, что запрос помечен для сбоя, и возвращает сбойный ответ. Как и прежде, экспериментальный кластер в качестве неудачного ответа из кэша выполнит код для обработки сбоя. Мы делаем это исходя из предположения, что он устойчив к сбоям, верно? Но иногда мы видим, что это не так. С точки зрения сервиса А всё выглядит как нормальное поведение.

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

Мы смотрим на ключевые бизнес-метрики. Одна из них называется SPS (stream starts per second), то есть запуски видеопотоков в секунду. Если подумать, что самое важное для бизнеса Netflix, так это чтобы пользователи могли запустить любой сериал в любое время, когда им захочется.



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

По этой причине в тесте используется автоматизированный canary-анализ. Он даёт сигнал, что очень графики сильно отклонились друг от друга. В этом случае тест немедленно прерывается, чтобы люди могли нормально работать с сайтом. С точки зрения пользователя это больше похоже на кратковременный глюк, когда такое происходит.

У нас есть много других средств защиты. Мы ограничиваем объём тестового трафика в каждом регионе, так что не проводим эксперимент только в зоне U.S. West 2. Мы делаем их повсюду и ограничиваем количество экспериментов, которые могут выполняться в регионе за один раз. Тесты проходят только в рабочее время, поэтому мы не будим инженеров, если что-то пойдёт не так. Если тест проваливается, его нельзя автоматически запустить снова, пока кто-нибудь явно вручную не исправит его и не подтвердит: «Эй, я знаю, что тест не прошёл, но я исправил всё, что нужно».

Есть возможность применять к кластерам пользовательские свойства. Это полезно, если сервис разделён на шарды, как многие сервисы Netflix. Кроме того, можно внедрять сбои с учётом типа устройства. Если мы предполагаем какие-то проблемы на устройствах Apple или у определённого типа телевизоров, то можем провести тесты конкретно на них.

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

Вот ещё один пример. Мы провели эксперимент, чтобы воспроизвести проблему в процессе регистрации, которая проявилась ночью на некоторых серверах. С сервисом происходило нечто странное. Проблему удалось воспроизвести после введения задержки на 500 миллисекунд. Во время теста проблему удалось найти в логах, загруженных на Big Data Portal. Это помогло понять, почему в некоторых случаях регистрация не срабатывала. Только благодаря эксперименту ChAP удалось посмотреть, что происходит и почему.

Для настройки теста ChAP требуется много информации. Нужно выяснить подходящие точки внедрения багов. Команды должны определить, они хотят получить сбой или задержку. Всё зависит от точки инъекции. Вы можете вызвать сбой Cassandra, Hystrix (наша резервная система), RPC-сервиса, RPC-клиента, S3, SQS или нашего кэша, или добавить задержку от них. Или сделать и то, и другое. Можно ещё придумать комбинации из разных экспериментов.

Что нужно сделать, так это собраться с группой обслуживания и придумать хороший тест. Это займёт очень много времени. При настройке эксперимента следует также определить конфигурации ACA (Automated Canary Analysis) или автоматические canary-конфигурации.

У нас было несколько готовых конфигураций ACA. Была одна конфигурация ChAP для SPS. Была одна с мониторингом системных показателей. Ещё одна, которая проверяла сбои RPS. Ещё одна следила за тем, что наш сервис на самом деле работает нормально и как следует внедряет баги. Мы поняли, что проектирование теста может оказаться весьма трудоёмким, так оно и вышло. Тестов создавалось не так много. Человеку трудно держать в голове всё, что нужно для хорошего эксперимента. Мы решили автоматизировать кое-что с помощью ChAP. Мы смотрели на индикаторы: куда и от кого идут вызовы, файлы с таймаутами, повторные вызовы. Стало понятно, что вся информация поступает из разных мест. Нужно было её агрегировать.

Мы масштабировали анализ до уровня ChAP, где с информацией гораздо удобнее работать и можно использовать Monocle. Теперь всю информацию о приложении и кластере можно изучать в одном месте. Здесь каждая строка представляет зависимость, а эти зависимости — питательная среда для экспериментов хаос-инжиниринга.

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

Каждая строка представляет зависимость, и эти строки можно развернуть. Вот интересный пример.



Здесь синяя линия вверху обозначает чей-то таймаут, а фиолетовая линия внизу показывает обычное время выполнения. Как видите, оно очень, очень далеко от таймаута. Но большая часть этой информации была недоступна. Что произойдёт, если мы проведём тест прямо под таймаутом? Как думаете? Он пройдёт? Это интересный вопрос. Мы пытаемся предоставить пользователям такой уровень детализации до запуска тестов, чтобы они могли сделать выводы и изменить настройки.

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





Чтобы дать вам некоторый контекст, удалённая команда Hystrix вмещает в себя и sample-rest-client, и sample-rest-client.GET. Таймаут Hystrix установлен на 500 миллисекунд. У sample-rest-client.GET таймаут 200 мс с одной повторной попыткой, и это хорошо, потому что в сумме получается 400 миллисекунд, что вписывается в лимит Hystrix. У второго клиента таймауты в 100 и 600 с одной повторной попыткой.

В этом случае повторная попытка не может быть завершена с учётом таймаута оболочки Hystrix, то есть Hystrix отказывается от запроса, прежде чем клиент может получить ответ. Вот где кроется уязвимость. Мы предоставляем эту информацию пользователям. Что интересно, большая часть логики в реализации этих функций находится в разных местах, и раньше они не могли сопоставить эти вещи. Они думали, что всё нормально работает, а здесь баг.

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

При создании автоматических тестов мы также используем Monocle. Пользователь создаёт эксперимент на многочисленных типах входных данных. Мы всё это берём и автоматизируем создание таких тестов, чтобы пользователи не утруждали себя. Мы автоматически создаём и назначаем приоритеты для экспериментов Hystrix и экспериментов RPC с задержками и сбоями из-за задержек. Конфигурации ACA добавляются по умолчанию. У нас есть SPC, системные метрики, статистика запросов, а эксперименты запускаются автоматически. Также создаются приоритеты для экспериментов. Для них работает высокоуровневый алгоритм. Мы используем бакет со статистикой RPS. Мы используем несколько повторных попыток и соответствующих команд Hystrix. Весь набор взвешен надлежащим образом.

Кроме того, принимается во внимание количество команд без резервных путей выполнения и любое внешнее воздействие (curated impact), которое клиент добавляет в свою зависимость. Внешнее воздействие сильно влияет на процедуры авторизации, регистрации и SPS. И мы реально измеряем его воздействие и не проводим эксперименты, если результат отрицательный. Затем тесты ранжируются и запускаются в порядке убывания критичности. Чем выше балл критичности, тем раньше и чаще запускается тест.

По иронии, Monocle обеспечил нам обратную связь, которая позволяет проводить меньше тестов в продакшне. Мы проводили так много тестов, что в результате образовался цикл обратной связи: мы увидели связи между тестами. Теперь можно посмотреть на определённые файлы конфигурации и увидеть определённые анти-шаблоны. Даже без тестов по этой информации можно понять, что именно вызовет сбой, в то время раньше мы этого не понимали.

Это привело к новому уровню безопасности. Раньше неудачный эксперимент помечался как решённый. Сейчас он помечается как решённый перед повторным запуском. Но теперь мы можем явно добавить внешние (кураторские) воздействия к зависимости. Пользователь входит в свой Monocle и указывает: вот этот фактор точно влияет на процедуру авторизации. Этот — на SPC. И мы работаем над циклом обратной связи, чтобы при неудаче тоже добавлялось такое кураторское воздействие.

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

Спасибо.
Tags:
Hubs:
Total votes 15: ↑12 and ↓3+9
Comments0

Articles