Как настроить таргетинг на пользователей с помощью Nginx Analytics и A / B-тестирования

Вступление

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

В этом руководстве мы рассмотрим набор функций, которые могут помочь в тестировании нового контента и сбора статистики о ваших пользователях. Они могут быть чрезвычайно полезны для целей разработки контента, для простого A / B-тестирования и для изучения поведения различных групп пользователей, которые посещают ваши сайты. Nginx имеет возможность легко включать эти функции в сам веб-сервер.

Простое A / B-тестирование с модулем Split Clients

Мы начнем с того, что покажем, как настроить базовое A / B-тестирование с помощью самого Nginx. Мы можем сделать это с помощью стандартного модуля HTTP с именем + http_split_clients +. Если явно не отключено во время пользовательской компиляции, это должно быть доступно в любой стандартной установке Nginx.

Модуль предоставляет единственную директиву, которая, что неудивительно, называется + split_clients +, которая разделяет запросы на соединение на две или более категории в зависимости от настроенных требований. Эта директива определяется в контексте + http + вне каких-либо серверных блоков. Он определяет значение для проверки в каждом соединении и создает переменную, в которой будут сохраняться результаты.

Основной синтаксис директивы выглядит примерно так:

http {

   . . .

   split_clients "" $ {
       %        ;
       %        ;
   }

}

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

Строки в блоке + split_clients + представляют различные «сегменты» или альтернативы, которые определяются процентом, который они должны использовать от доступного пространства хеша. Это создает «диапазоны» хешей, которые соответствуют определенному количеству хешей, определяемому указанным процентом. Каждый из них определяет значение, которое должно быть установлено, когда хеш находится в пределах диапазона этого сегмента. Вторая переменная, заданная во время определения + split_clients +, устанавливается на это значение.

Это гораздо проще понять при рассмотрении примера. Взгляните на следующий блок:

split_clients "${remote_addr}" $designtest {
   10%         ".first";
   10%         ".second";
   *           "";
}

В приведенном выше примере мы оцениваем значение соединения для + $ remote_addr +, которое Nginx устанавливает в IP-адрес клиента. Значение IP-адреса клиента хэшируется с использованием алгоритма хэширования murmurhash2. На этом этапе Nginx проверяет, к какому диапазону хешей относится рассчитанный хеш. Поскольку в реализации murmurhash2, которую использует Nginx, используются 32-битные значения, хэши будут находиться в диапазоне от 0 до 4294967295 (максимальное 32-битное число).

Поскольку первая определенная группа задает 10% от общего числа хэшей, она будет соответствовать от 0 до 429496729, что является первой десятой доступного диапазона. Значения, которые создают хэш в этом диапазоне, будут устанавливать для переменной + $ designtest + значение «.first».

IP-адреса с хэшами примерно от 429496730 до 858993459, диапазон хэшей, представленный следующими 10% доступных хэшей, будет соответствовать второй строке. В этих случаях переменная + $ designtest + будет установлена ​​в «.second».

Для всех других хешей IP-адресов (примерно от 858993460 до 4294967295) переменная + $ designtest + будет установлена ​​в пустую строку.

Как реализовать это на сервере

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

Например, мы могли бы добавить сервер и блок местоположения, который обслуживает различное содержимое в зависимости от значения переменной + $ designtest +. В приведенном ниже примере эта переменная используется для определения, какой индексный файл обслуживать:

http {

   . . .

   split_clients "${remote_addr}" $designtest {
       10%     ".first";
       10%     ".second";
       *       "";
   }

   server {
       listen 80;
       server_name localhost;
       root /usr/share/nginx/html;

       index index${designtest}.html;

       location / {
           try_files $uri $uri/ =404;
       }
   }
}

Для IP-адресов с хэшами, которые попадают в первую группу, Nginx попытается обработать файл с именем + index.first.html +. Аналогично, для IP-адресов, попадающих во вторую группу, Nginx будет искать файл с именем + index.second.html +. Если IP-адрес находится в третьей группе, переменная + $ designtest + будет установлена ​​в пустую строку, поэтому будет использован обычный файл + index.html +.

Теперь, если мы создадим три файла индекса в корне нашего документа, они будут предоставлены разным пользователям в зависимости от результирующего хеша их IP-адреса:

echo "<h1>First Site</h1>" | sudo tee /usr/share/nginx/html/index.first.html
echo "<h1>Second Site</h1>" | sudo tee /usr/share/nginx/html/index.second.html
echo "<h1>Default Site</h1>" | sudo tee /usr/share/nginx/html/index.html

Если вы внесете вышеуказанные изменения в конфигурацию Nginx и перезапустите веб-сервер, вы можете проверить это. Мы можем проверить, что наш конфигурационный файл не имеет синтаксических ошибок, а затем перезапустить службу, набрав:

sudo nginx -t
sudo service nginx restart

Если мы посетим сайт в нашем браузере, мы увидим один из трех файлов выше. Вероятно, он будет последним, поскольку будет обслуживаться 80% посетителей сайта. Если вы хотите увидеть, как он будет отображаться для других пользователей, вы можете посетить сайт через прокси-сервер или с помощью некоторых веб-инструментов.

Например, сайт GeoPeeker можно использовать для просмотра вашего сайта из разных мест по всему миру. Если вы введете свое доменное имя, вы можете увидеть хотя бы один из ваших альтернативных сайтов:

изображение: https: //assets.digitalocean.com/articles/nginx_testing/ab_testing.png [Альтернативные индексы сайта]

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

Хотя приведенный выше пример прост, концепция может быть значительно расширена. Вы можете использовать переменные, установленные директивой + split_clients +, для установки файлов cookie и идентификаторов пользователей, передачи заголовков во внутренние прокси-серверы и т. Д. Если вы хотите более полно A / B-тестирование, вы можете использовать переменную, которую вы установили, чтобы определить, какой корень документа будет подан различным сторонам.

Также важно помнить, что проверка + $ {remote_addr} + является просто полезным примером. Вы можете хешировать, основываясь на значении любой переменной Nginx, которая работает в строках. Вы можете найти список тех, которые включены в модуль Core here, хотя другие переменные доступны через другие модули. Проверьте документацию для получения дополнительной информации.

Установка пикселей отслеживания с помощью директивы empty_gif

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

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

Модуль + empty_gif + предоставляет эту функциональность в Nginx. Хотя любой запрос может использоваться для отслеживания, директива + empty_gif + позволяет вам обслуживать крошечный прозрачный файл + .gif +, который существует в памяти, избегая доступа к диску. Это ускорит запросы на этот ресурс. Директива действительна в любом контексте местоположения.

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

. . .

http {

   log_format tracking '[$time_local] : $remote_addr : $remote_user : '
                       '$args : $http_referer : $http_user_agent';

   server {

       . . .


       location = /logme.gif {
           empty_gif;
           access_log /var/log/nginx/tracking.log tracking;
           expires epoch;
       }
   }
}

Здесь мы устанавливаем + log_format + в контексте + http + для записи информации, которую мы хотим отслеживать. Это может быть что угодно.

После этого мы можем настроить блок местоположения, чтобы он соответствовал конкретному запросу + .gif +. Мы используем модификатор + = +, чтобы любые запросы для + .gif + были сопоставлены быстро и эффективно без поиска лучших совпадений в другом месте. Вы можете выбрать любое имя + .gif +.

Внутри мы используем директиву + empty_gif + для обслуживания прозрачного пикселя 1x1 + .gif + из памяти. Мы сообщаем запросам этого местоположения для входа в отдельный файл, используя формат, который мы указали ранее. Наконец, мы устанавливаем для expire значение «epoch», что должно информировать браузеры не кэшировать + .gif +, что позволяет нам отслеживать каждый раз, когда посетитель попадает на страницу.

Теперь мы можем добавить изображение, запрашивающее выбранное нами изображение на наших страницах. Например, очень простая страница может выглядеть так:

<html>
   <head>
       <title>Your Site</title>
   </head>
   <body>
       <h1>Normal Content</h1>
       <img src="/logme.gif">
   </body>
</html>

Когда посетитель заходит на эту страницу, запрашивается изображение + / logme.gif +, в результате чего Nginx записывает в наш файл + tracking.log + подробную информацию о запросе. Это может быть встроено в более сложную систему путем настройки + log_format + и анализа ваших журналов с помощью инструментов обработки текста.

Дифференциация контента на основе географии

Ранее мы показали, как настроить Nginx для автоматического разделения пользователей на группы с целью A / B-тестирования с помощью модуля + split_clients +. Nginx также может автоматически разделять пользователей на группы в зависимости от местоположения их IP-адреса.

IP-адреса сопоставляются с приблизительными местоположениями с использованием набора таблиц, которые составляются определенными поставщиками. Они получают эту информацию главным образом из многочисленных реестров, которые отвечают за распределение пространства IP в различных географических областях. Информация, которую можно получить с чьего-либо IP-адреса, является лишь приблизительной и должна использоваться в качестве «наилучшего предположения», а не высокоточного метода определения источника трафика.

Приобретение баз данных местоположения

Nginx может использовать эти данные для разделения клиентов, используя различные директивы, включенные в модуль + ngx_http_geoip_module +. Базы данных сопоставлений IP-адресов и местоположений не включены, поэтому вам придется приобретать их отдельно.

В Ubuntu вы можете получить сопоставления на уровне страны, набрав:

sudo apt-get update
sudo apt-get install geoip-database

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

sudo mkdir -p /usr/local/share/GeoIP
cd /usr/local/share/GeoIP
sudo wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz

Нам нужно распаковать файл, набрав:

sudo gunzip GeoIP.dat.gz

Для более конкретной базы данных на уровне города вы также можете скачать с помощью + wget +:

sudo mkdir -p /usr/local/share/GeoIP
cd /usr/local/share/GeoIP
sudo wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz

Опять же, нам нужно распаковать файлы:

sudo gunzip GeoLiteCity.dat.gz

Настройка Nginx для использования данных о местоположении

После того, как у нас есть базы данных о местонахождении, мы можем настроить Nginx для использования этих данных.

Мы можем указать Nginx, где найти каждую из баз данных на диске, установив следующие директивы. Они должны быть установлены в контексте + http + в файле конфигурации Nginx:

. . .

http {
   # If you downloaded the country-level data using `apt-get` uncomment and use:
   #geoip_country /usr/share/GeoIP/GeoIP.dat;
   # If you downloaded the country-level data using `wget`, use:
   geoip_country /usr/local/share/GeoIP/GeoIP.dat;
   geoip_city /usr/local/share/GeoIP/GeoLiteCity.dat;

   . . .
}

После определения местоположения вы можете использовать переменные, которые Nginx использует для каждой из этих баз данных. База данных на уровне страны дает нам доступ к следующим переменным:

  • * + $ geoip_country_code + *: двухбуквенный код страны, используемый для представления страны. Например, «США» для США или «RU» для России. Их можно найти here.

  • * + $ geoip_country_code3 + *: Почти то же, что и выше, но с использованием трехбуквенного варианта. Например, «США» или «RUS».

  • * + $ geoip_country_name + *: имя, сопоставленное с кодом страны, как показано в связанном списке. Например, «Новая Зеландия» для «NZ».

База данных на уровне города предоставляет нам большее количество переменных. С этой базой данных у нас есть доступ к:

  • * + $ geoip_area_code + *: Устаревшее поле кода города для телефонных номеров США. Это не следует полагаться на точные данные.

  • * + $ geoip_city_continent_code + *: двухбуквенный код континента.

  • * + $ geoip_city_country_code + *: тот же двухбуквенный код страны, который предоставляется базой данных на уровне страны.

  • * + $ geoip_city_country_code3 + *: тот же трехбуквенный код страны, который предоставляется базой данных на уровне страны.

  • * + $ geoip_city_country_name + *: то же название страны, что и в базе данных на уровне страны.

  • * + $ geoip_dma_code + *: регион DMA или код метро для местоположений в США. Это можно найти в Google AdWords API, который находится по адресу here.

  • * + $ geoip_latitude + *: оценка широты исходного IP.

  • * + $ geoip_longitude + *: оценка долготы исходного IP.

  • * + $ geoip_region + *: двухсимвольный код региона, используемый для обозначения политического региона, такого как территория, штат, провинция и т. д.

  • * + $ geoip_region_name + *: полное имя, связанное с указанным выше кодом региона.

  • * + $ geoip_city + *: название города, связанное с исходным IP-адресом.

  • * + $ geoip_postal_code + *: почтовый индекс области, в которой находится IP.

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

Часто мы будем использовать одну из указанных выше переменных с директивой + map +, чтобы условно установить значение другой переменной. Это позволяет нам создать переменную со значением, определяемым тем, что база данных сообщает нам о местонахождении клиента.

Директива + map + также должна использоваться в контексте + http +. Например, мы можем настроить наш сайт для отображения различного контента, если посетитель из Австралии или Сингапура. Наилучший способ проверить это, вероятно, с помощью одного из двух- или трехбуквенных кодов стран, найденных в базах данных страны или города.

Мы будем использовать + $ geoip_country_code + для этого примера. Значение этой переменной будет определять то, что мы храним в переменной + $ site_version +, которую мы создаем. Мы будем использовать это, чтобы определить корень документа, из которого нужно подавать:

http {
   # If you downloaded the country-level data using `apt-get` uncomment and use:
   #geoip_country /usr/share/GeoIP/GeoIP.dat;
   # If you downloaded the country-level data using `wget`, use:
   geoip_country /usr/local/share/GeoIP/GeoIP.dat;
   geoip_city    /usr/local/share/GeoIP/GeoLiteCity.dat;

   map $geoip_country_code $site_version {
       default     "";
       AU          "/australia";
       SG          "/singapore";
   }

   . . .
}

Это устанавливает значение + $ site_version +, переменной, которую мы создаем специально для этой цели. Если код страны посетителя указывает, что он из Австралии (+ AU +), мы установим для + $ site_version + значение “/ australia”. Если посетитель из Сингапура («SG»), мы установим для «+ $ site_version » значение «/ singapore». Если их код страны указывает любое другое значение, мы установим для ` $ site_version +` пустую строку.

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

Чтобы изменить корень документа, нам просто нужно установить директиву + root + в блоке сервера следующим образом:

http {
   # If you downloaded the country-level data using `apt-get` uncomment and use:
   #geoip_country /usr/share/GeoIP/GeoIP.dat;
   # If you downloaded the country-level data using `wget`, use:
   geoip_country /usr/local/share/GeoIP/GeoIP.dat;
   geoip_city    /usr/local/share/GeoIP/GeoLiteCity.dat;

   map $geoip_country_code $site_version {
       default     "";
       AU          "/australia";
       SG          "/singapore";
   }

   . . .

   server {
       . . .



       . . .

   }
}

Если пользователь из Австралии, корень документа для обслуживания запросов будет изменен на + / usr / share / nginx / html / australia +. Аналогичным образом, для посетителей из Сингапура контент будет обслуживаться из + / usr / share / nginx / html / singapore +. Для других посетителей переменная + $ site_version + была установлена ​​в пустую строку, поэтому они будут продолжать получать контент из + / usr / share / nginx / html +.

Мы можем установить корневой каталог документов по умолчанию + / usr / share / nginx / html +, чтобы легко это проверить. Начните с перемещения в это место:

cd /usr/share/nginx/html

Затем мы можем создать каталоги, которые мы упомянули, и вставить некоторое очень простое содержимое в файл + index.html + внутри каждого из новых каталогов. Это позволит нам увидеть, влияет ли наше местоположение на обслуживаемый нами контент:

sudo mkdir australia && echo "<h1>australia</h1>" | sudo tee australia/index.html
sudo mkdir singapore && echo "<h1>singapore</h1>" | sudo tee singapore/index.html

После того, как все это настроено, мы можем проверить нашу конфигурацию и перезагрузить Nginx:

sudo nginx -t
sudo service nginx restart

Теперь мы можем снова воспользоваться сайтом GeoPeeker, чтобы проверить, обслуживается ли нам разный контент из разных мест. Как Австралия, так и Сингапур - это варианты, которые сайт позволяет вам проверить.

Здесь вы можете увидеть страницу по умолчанию для посетителя из США или Ирландии, а также тестовый текст, который мы добавили для посетителей из Австралии или Сингапура:

изображение: https: //assets.digitalocean.com/articles/nginx_testing/geo_differences.png [Различия в геолокации]

Это подтверждает, что Nginx правильно выбирает контент для обслуживания, сверяя IP-адрес клиента с базой данных местоположений.

Заключение

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