Pull to refresh

Пример удобной организация split (A/B) тестирование на серверной стороне

Reading time3 min
Views3.1K
Здравствуйте, уважаемые хабравчане!
Хотел бы поделится с Вами некоторым опытом организации split тестирование на проекте с которым довелось работать, также прошу не судить строго, так как это моя первая статья и действительно огромного профита ожидать не стоит.
Как мы все знаем, split (A/B) тестирование на сайте представляет собой экспериментальный подход с целью повышение конверсии по какому-либо процессу на ресурсе путем отображения различным группам пользователей разного контента.

Целью поставленной задачи была организация довольно сложного тестирования разных вариантов контента (как статических, так и динамических), с возможным неограниченным количеством экспериментов и вариантов на каждой странице ресурса. Проведя некий анализ имеющихся готовых решений поставленной задачи удалось найти несколько вариантов — это были GWO(уже не существует как отдельный сервис, интегрирован в GA), решение на основе nginx и Visual Website Optimizer. Но не один из них не подходил по ряду причин: внешние сервисы переносят рендеринг на сторону клиента, что при сложных тестах бывает очень не удобно, а nginx стоит далеко не везде, плюс не всегда у разработчиков есть доступ к конфигурации веб сервера и также возникает проблема размазывания логики. Потому мной было принято решение реализации своего велосипеда варианта, основываясь на примере реализации модуля nginx.
Стандартные советы по реализации ( остаток от делания последней цифры IP адреса клиента и тд. ) мне также не нравились, потому решил для определения вариантов использовать контрольные суммы от ключа тестирования — профит варианта в использовании абсолютно любого буквенно-цифрового ключа, возможности создания огромного количества вариантов тестирования с любым процентным отношением. Выбор хеш функции пал на MurmurHash2, так как она характеризуется очень хорошим распределением и, чего уж скрывать, используется для хеширования в модуле nginx. Проект над которым я работаю реализован на php, для реализации хеш функции рекомендую использовать данное расширение.
Теперь же коснемся более реализации. Для определения значения варианта тестирования по конкретному эксперименту я реализовал класс SplitTestModel, используя его как синглтон:
class SplitTestModel
{
public static function getInstance($key = ''){...}
private function __construct( $key ){...}
public function getSplitVariantByExperiment( $experimentName ){...}
}

Информацию о каждом эксперименте я в вынес в конфиг, которые представляет собой, в моей реализации, массив вида:
array(
    'Experiment1' => array(
        'Variant1' => 50,
        'Variant2'   => 50
    ),
    'Experiment2' => array(
        'Variant1' => 15,
        'Variant2' => 35,
        'Variant3' => 12,
        'Variant4' => *
    )
);

Где ключ верхнего уровня — названия эксперимента, вложенные ключи — названия вариантов, а соответствующие им значения — процент показов, '*' означает все оставшиеся проценты.
Как уже возможно стало понятно, ключ хэшируется с помощью MurmurHash2. В приведенном по первому эксперименту примере при значениях хэша от 0 до 50 % от максимально возможного значения хеша, пользователь получит вариант значения равный 'Variant1', от 50 % от максимально возможного значения до 100% — соответственно значение 'Variant2'.
Удобство метода заключается в том, что теперь в любом месте кода, для конкретного пользователя мы можем получить его значения варианта по любому из экспериментов и в зависимости от варианта отдать клиенту тот или иной контент любой части страницы. Пример использования:
$variant1 = SplitTestModel::getInstance($user_id)->getSplitVariantByExperiment('experiment1');
$variant2 = SplitTestModel::getInstance($remote_addr)->getSplitVariantByExperiment('experiment2');

Все предельно просто!
Большое спасибо за внимание, и еще раз попрошу не судить строго. Если кому-либо будет интересно с удовольствием пришлю исходный код класса.

UPD:
ссылка на реализацию класса на github
Tags:
Hubs:
+4
Comments5

Articles

Change theme settings