Способ тестирования изменений сервиса через shadow-трафик
Проблема
Пример из реальной жизни - я работаю над одним из высоко нагруженных компонентов системы, который обрабатывает 1,5-2 млн запросов в минуту (33 k RPS).
Наш сервис уже стал сложным для внесения изменений, а внутренний механизм устарел и не соответствует новым требованиям бизнеса. Он также уже почти не может быть ускорен и имеет технические проблемы. Мы спланировали и разработали новый механизм работы и обработки данных (изменено около 40% кодовой базы), который нужно интегрировать и перенаправить на него трафик. Все старые тесты были пройдены и показали, что все работает хорошо. Несмотря на это, нет уверенности в качестве наших тестов, и не все сценарии были покрыты.
Решение
У нас были разные подходы и идеи для проверки работы на реальных данных. Однако, мы выбрали идею повторного запроса для части трафика. Нам помог shadow-трафик - подход, при котором часть трафика (запросов) обрабатывается повторно другим механизмом и ответы сравниваются.
Как выглядит на практике
Мы написали утилиту, в которую можно скормить 2 json ответа и получить:
- дифф объектов
- список полей, которые различаются
- метрика сколько ответов совпало, а сколько различается
Дифф и запрос логировали, а по кажлому полю записывали отдельную метрику. Метрики по совпадению ответов превратили в график, который показывал сходимость механизма (совпадаюющие запросы / общее количество).
Результаты
Этот подход помог нам выявить множество проблем. В результате мы обнаружили ошибки в новом механизме, которые не были найдены на стадии тестирования. Покрыли все сценарии тестами и увеличили уверенность в качестве наших тестов.
Из забавного, обнаружили проблемы в старом механизме, который все еще обрабатывает часть трафика. Сходимость старого механизма со старым не была 100% xD
Проблемы подхода
На практике невозможно окончательно подвтердить отсутствие проблем, необходима большая выборка запросов для точного подтверждения отсутствия проблем. Однако, ошибки могут возникнуть на сверхмалом количестве запросов или спустя долгое время после запуска.
Выводы
В итоге, использование shadow-трафика оказалось эффективным подходом для проверки работы системы на реальных данных. Это помогло нам улучшить качество системы и снизить риски при переводе трафика на новый механизм. С помощью этого способа получилось обнаружить проблемы, которые не нашли тестами и дополнительно покрыли. Мы добивали сходимость до 99.99% чтобы разблокировать раскатку и все получилось.
Реализация
Реализовать на практике достаточно просто, приведу простой пример кода на golang. По комментариям общую логику возможно воспроизвести как угодно. В идеале, реализовать как дополнительную middleware, чтобы не дублировать код во всех обработчиках, но в примере показан базовый сценарий. Процентом трафика также возможно гибко управлять например через свои кастомные переключатели, либо просто релизами. Советую не ставить процент больше 10, т.к это дополнительные 10% запросов на сервис, может сильно вырасти нагрузка.
Логика в обработчике
|
|
Презентация
Дополнительные источники для изучения
Весь исходный код доступен на github
Видео на youtube