A/B тестирование. Маршрутизация клиентов в шлюзе API
Я работаю над новым проектом, который будет основан на микросервисах. Это внутреннее приложение и всего около 10 микросервисов. Мы будем использовать API шлюза для аутентификации и, возможно, агрегации микросервисов. (Возможно Netflix zuul с Spring Boot)
Я не совсем понимаю, как мы выполняем маршрутизацию для A/B-тестирования и Canary-тестирования. Предположим, у меня есть 100 клиентов, и мы хотим провести A/B-тестирование новой версии микросервиса. Клиентское приложение не нуждается в изменениях, это просто внутренние изменения в функции, предоставляемой микросервисом.
Я понимаю, что мы бы поддержали новый микросервис, который, скажем, v2. Я озадачен тем, как направить (скажем) клиентов 1-10 к новой версии. Мы должны иметь возможность настроить это централизованно и ничего не менять на клиенте.
Мы знаем их MAC-адреса (а также другие идентифицирующие атрибуты) и можем вставить любой заголовок, который мы хотим идентифицировать в их сообщениях.
Итак, как бы я направил их в v2 API для тестирования A/B или развертывания Canary?
3 ответа
Я опубликовал прототип на Github, который показывает, как можно добиться маршрутизации с помощью Zuul Gateway
, Этот прототип просто показывает, как вы можете направлять трафик на основе куки в разные экземпляры одного и того же приложения. Вы можете сделать маршрутизацию на основе любых других критериев. Вы также должны взглянуть на Spring Cloud Gateway
в качестве альтернативы Zuul
, Кажется, очень перспективным. https://github.com/adiesner/spring-boot-sample-ci-gateway
Более простой настройкой было бы просто добавить nginx перед вашим сервисом и использовать метод split_clients.
http {
# ...
# application version 1a
upstream version_1a {
server 10.0.0.100:3001;
server 10.0.0.101:3001;
}
# application version 1b
upstream version_1b {
server 10.0.0.104:6002;
server 10.0.0.105:6002;
}
split_clients "${arg_token}" $appversion {
95% version_1a;
* version_1b;
}
server {
# ...
listen 80;
location / {
proxy_set_header Host $host;
proxy_pass http://$appversion;
}
}
}
https://www.nginx.com/blog/performing-a-b-testing-nginx-plus/
Если описать общий подход высокого уровня, вы можете сделать что-то вроде этого:
- Вашим клиентам необходимо иметь некоторые параметры, которые позволят однозначно их идентифицировать. Похоже, у вас уже есть это.
- Внедрить дополнительный сервис API (назовем его Experiment API). Эта служба должна иметь хотя бы одну конечную точку, которая получает идентифицирующие атрибуты клиента и сообщает, участвует ли клиент в A/B-тестировании или нет.
- При каждом входящем запросе API-интерфейс шлюза должен использовать эту конечную точку API эксперимента, чтобы решить, какую версию микросервиса (v1 или v2) использовать для перенаправления / вызова.
- Чтобы не вызывать Experiment API каждый раз, вы можете ввести некоторый уровень кэширования в Gateway API. В качестве другого варианта вы можете использовать какой-либо пользовательский файл cookie (который содержит информацию о клиенте в разделе "эксперимент"), вызывать API эксперимента только в том случае, если этот файл cookie не указан, и возвращать файл cookie клиенту с ответом.
Немного пояснить ответ @ Сета. Вам нужно будет ввести некоторый код инструментария в свой API шлюза, чтобы принять решение о том, какую конечную точку нисходящего направления вызывать. Если и только если единственным компонентом вашего распределенного бэкэнда, который связан с этим, является API шлюза, вышеприведенное решение является чрезмерно сложным: вы можете обойтись только с помощью библиотеки. Но вполне вероятно, что вы скоро обнаружите, что одна или несколько других ваших служб должны знать об эксперименте, и в этом случае вам действительно нужна отдельная услуга.
Вообще говоря, создание надежной среды для экспериментов является сложной задачей. Вы быстро столкнетесь с неожиданными проблемами, например, испытанием стабильности (как гарантировать такой же опыт для повторных посетителей) или как изменить пропорцию распределения (или, возможно, полностью отключить новый код) без необходимости перезапуска хост-приложения. Вы должны исследовать фреймворки с открытым исходным кодом или даже коммерческие инструменты на стороне сервера. (У нас есть один в Variant).