Comment cibler vos utilisateurs avec Nginx Analytics et A / B Testing

introduction

Nginx est un puissant serveur proxy et Web utilisé par certains des plus grands sites pour gérer les connexions client et diffuser du contenu. Bien que la plupart des utilisateurs soient familiarisés avec les fonctionnalités de base de Nginx, il existe d’autres fonctionnalités qui ne sont peut-être pas évidentes lors d’une utilisation typique.

Dans ce guide, nous allons explorer un ensemble de fonctionnalités permettant de tester de nouveaux contenus et de collecter des statistiques sur vos utilisateurs. Celles-ci peuvent s’avérer extrêmement utiles pour le développement de contenu, pour effectuer de simples tests A / B et pour connaître le comportement de différents groupes d’utilisateurs fréquentant vos sites. Nginx peut facilement intégrer ces fonctions au serveur Web lui-même.

Test simple A / B avec le module Clients divisés

Nous allons commencer par vous montrer comment configurer certains tests A / B de base via Nginx lui-même. Nous pouvons le faire avec un module HTTP standard appelé + http_split_clients +. À moins d’être explicitement désactivé lors d’une compilation personnalisée, celui-ci devrait être disponible dans toutes les installations Nginx standard.

Le module fournit une seule directive appelée, sans surprise, + split_clients + qui divise les demandes de connexion en deux catégories ou plus en fonction des exigences configurées. Cette directive est définie dans le contexte + http +, en dehors de tout bloc serveur. Il désigne la valeur à vérifier dans chaque connexion et crée une variable dans laquelle stocker les résultats.

La syntaxe de base de la directive ressemble à ceci:

http {

   . . .

   split_clients "" $ {
       %        ;
       %        ;
   }

}

La directive fonctionne en interpolant la valeur de la première variable transmise et en hachant le résultat. La même valeur produira toujours le même hachage, permettant des résultats cohérents. La variable en cours de vérification doit générer une chaîne lors de l’évaluation.

Les lignes du bloc + split_clients + représentent différents «compartiments» ou alternatives définis par le pourcentage qu’ils doivent consommer de l’espace de hachage disponible. Cela crée des «plages» de hachage qui correspondent à un certain nombre de hachages déterminés par le pourcentage fourni. Chacune de celles-ci définit une valeur qui doit être définie lorsque le hachage se situe dans la plage de ce compartiment. La deuxième variable donnée lors de la définition + split_clients + est définie sur cette valeur.

C’est beaucoup plus simple à comprendre lorsqu’on considère un exemple. Jetez un coup d’œil au bloc suivant:

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

Dans l’exemple ci-dessus, nous évaluons la valeur de la connexion pour «+ $ remote_addr +», qui est définie par Nginx sur l’adresse IP du client. La valeur de l’adresse IP du client est hachée à l’aide de l’algorithme de hachage murmurhash2. À ce stade, Nginx vérifie la plage de hachages dans laquelle se trouve le hachage calculé. Étant donné que l’implémentation murmurhash2 utilisée par Nginx utilise 32 bits, les hachages seront compris entre 0 et 4294967295 (le nombre le plus élevé sur 32 bits).

Comme le premier groupe défini spécifie 10% du total des hachages, cela correspond à 0 à 429496729, ce qui correspond au premier dixième de la plage disponible. Les valeurs produisant un hachage dans cette plage attribueront à la variable + $ designtest + la valeur de «.first».

Les adresses IP avec des hachages d’environ 429496730 à 858993459, la plage de hachage représentée par les 10% suivants des hachages disponibles, correspondront à la deuxième ligne. Dans ces cas, la variable + $ designtest + sera définie sur «.second».

Pour tous les autres hachages d’adresse IP (environ 858993460 à 4294967295), la variable + $ designtest + sera définie sur une chaîne vide.

Comment implémenter ceci sur un serveur

Cela nous permet essentiellement de mapper de manière aléatoire un certain pourcentage de connexions sur différentes valeurs de variables. Une fois que cela est fait, nous pouvons utiliser cette variable pour servir un contenu différent.

Par exemple, nous pourrions ajouter un bloc serveur et emplacement qui sert un contenu différent en fonction de la valeur de la variable + $ designtest +. L’exemple ci-dessous utilise cette variable pour décider quel fichier d’index servir:

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;
       }
   }
}

Pour les adresses IP dont le hachage appartient au premier groupe, Nginx essaiera de servir un fichier nommé + index.first.html +. De même, pour les adresses IP appartenant au deuxième groupe, Nginx recherchera un fichier appelé + index.second.html +. Si l’adresse IP est dans le troisième groupe, la variable + $ designtest + sera définie sur une chaîne vide, de sorte qu’un fichier + index.html + conventionnel sera servi.

Maintenant, si nous créons les trois fichiers d’index dans notre racine de document, ils seront servis à différents utilisateurs en fonction du hash résultant de leur adresse 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

Si vous apportez les modifications ci-dessus à votre configuration Nginx et redémarrez le serveur Web, vous pouvez le tester. Nous pouvons vérifier que notre fichier de configuration n’a pas d’erreur de syntaxe, puis redémarrer le service en tapant:

sudo nginx -t
sudo service nginx restart

Si nous visitons le site dans notre navigateur, nous verrons l’un des trois fichiers ci-dessus. Probablement, ce sera le dernier car il sera servi à 80% des visiteurs du site. Si vous souhaitez voir son affichage pour les autres utilisateurs, vous pouvez visiter le site via un serveur proxy ou à l’aide d’outils Web.

Par exemple, le site GeoPeeker peut être utilisé pour afficher votre site depuis divers endroits du monde. Si vous tapez votre nom de domaine, vous pouvez voir au moins un de vos sites alternatifs:

image: https: //assets.digitalocean.com/articles/nginx_testing/ab_testing.png [Index de sites alternatifs]

Un autre site similaire est LocaBrowser, qui vous permet de choisir parmi plusieurs pays. N’oubliez pas que la division des pages en cours de traitement n’est pas basée sur la géolocalisation, mais sur le hachage de l’adresse IP. Cela ne signifie donc pas que tous les visiteurs d’un pays donné recevront le même fichier.

Bien que l’exemple ci-dessus soit simple, le concept peut être considérablement développé. Vous pouvez utiliser les variables définies par la directive + split_clients + pour définir les cookies et les identifiants d’utilisateur, passer les en-têtes aux serveurs mandataires, etc. Si vous souhaitez effectuer un test A / B plus complet, vous pouvez utiliser la variable que vous avez définie pour déterminer la racine du document qui sera transmise à différentes parties.

Il est également important de se rappeler que la vérification + $ {remote_addr} + n’est qu’un exemple utile. Vous pouvez effectuer un hachage en fonction de la valeur de n’importe laquelle des variables de Nginx qui fonctionne dans les chaînes. Vous pouvez trouver une liste de ceux inclus dans le module principal here, bien que d’autres variables soient disponibles via d’autres modules. Pour plus d’information, regardez la documentation.

Définition de pixels de suivi avec la directive empty_gif

Le suivi des pixels est un moyen utilisé par les administrateurs pour rendre compte des utilisateurs qui visitent leur site. Le suivi des pixels est un moyen inoffensif pour les administrateurs de collecter des données sur les adresses IP visitées, sur quelles pages et à quelle heure, via une simple journalisation.

Un pixel de suivi traditionnel fonctionne en incorporant une petite image transparente sur la page. Lorsqu’un utilisateur visite le site, l’image est demandée dans le cadre du processus de chargement de la page. L’administrateur peut mettre ces demandes dans un journal séparé, avec l’adresse IP d’où provient la demande, la page que le client chargeait lors de la demande, etc. Ce type d’information peut servir de base à l’analyse des données relatives aux actions des visiteurs sur votre site Web.

Le module + empty_gif + fournit cette fonctionnalité dans Nginx. Bien que n’importe quelle requête puisse être utilisée pour le suivi, la directive + empty_gif + vous permet de servir un minuscule fichier transparent + .gif + qui existe en mémoire, évitant ainsi l’accès au disque. Cela accélérera les demandes pour cette ressource. La directive est valide dans n’importe quel contexte d’emplacement.

Le plus souvent, cette directive est utilisée conjointement avec une directive de journal distincte pour séparer les demandes d’analyse ultérieure. Par exemple, votre configuration pourrait avoir une section qui ressemble à ceci:

. . .

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;
       }
   }
}

Ici, nous configurons un + log_format + dans le contexte + http + pour enregistrer les informations que nous souhaitons suivre. Cela peut être ce que vous voulez.

Ensuite, nous pouvons configurer un bloc d’emplacement pour qu’il corresponde à une requête + .gif + spécifique. Nous utilisons le modificateur + = + pour que toutes les demandes de + .gif + soient mises en correspondance rapidement et efficacement sans chercher de meilleures correspondances ailleurs. Vous pouvez choisir le nom + .gif + de votre choix.

A l’intérieur, nous utilisons la directive + empty_gif + pour servir le pixel transparent 1x1 + .gif + de la mémoire. Nous demandons aux demandes pour cet emplacement de se connecter à un fichier séparé en utilisant le format spécifié précédemment. Enfin, nous définissons l’expiration sur «epoch», ce qui devrait informer les navigateurs de ne pas mettre en cache le + .gif +, ce qui nous permet de suivre chaque fois que le visiteur accède à la page.

Maintenant, nous pouvons ajouter une image demandant l’image que nous avons sélectionnée à nos pages. Par exemple, une page extrêmement simple pourrait ressembler à ceci:

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

Lorsqu’un visiteur accède à cette page, l’image + / logme.gif + sera demandée, ce qui obligera Nginx à écrire dans notre fichier + tracking.log + avec des détails sur la demande. Cela peut être construit sur un système plus sophistiqué en peaufinant votre + log_format + et en analysant vos journaux à l’aide d’outils de traitement de texte.

Différencier le contenu en fonction de la géographie

Plus tôt, nous vous avons montré comment configurer Nginx pour diviser automatiquement les utilisateurs en groupes dans le but de tester A / B avec le module + split_clients +. Nginx peut également diviser les utilisateurs en groupes automatiquement en fonction de l’emplacement de leur adresse IP.

Les adresses IP sont mappées sur des emplacements approximatifs à l’aide d’un ensemble de tables compilées par certains fournisseurs. Ils reçoivent ces informations principalement de nombreux registres responsables de l’allocation d’espace IP dans différentes zones géographiques. Les informations pouvant être extraites de l’adresse IP d’une personne sont approximatives et doivent être utilisées comme une «meilleure estimation», par opposition à une méthode très précise d’identification de l’origine du trafic.

Acquisition des bases de données d’emplacement

Nginx peut utiliser ces données pour séparer les clients à l’aide de diverses directives incluses dans le module + ngx_http_geoip_module +. Les bases de données de mappages adresse IP / emplacement ne sont toutefois pas incluses. Vous devrez donc les acquérir séparément.

Sur Ubuntu, vous pouvez obtenir les mappages au niveau des pays en tapant:

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

Une méthode plus générique pour obtenir les mappages au niveau des pays consiste à télécharger les fichiers avec + wget +. Nous pouvons créer un répertoire pour stocker la base de données, puis télécharger le fichier en tapant:

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

Nous devons décompresser le fichier en tapant:

sudo gunzip GeoIP.dat.gz

Pour la base de données plus spécifique au niveau de la ville, vous pouvez également télécharger avec + 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

Encore une fois, nous devrons décompresser les fichiers:

sudo gunzip GeoLiteCity.dat.gz

Configuration de Nginx pour utiliser les données de localisation

Une fois les bases de données de localisation en place, nous pouvons configurer Nginx pour tirer parti des données.

Nous pouvons dire à Nginx où trouver chacune des bases de données sur disque en définissant les directives suivantes. Ceux-ci doivent être définis dans le contexte + http + dans le fichier de configuration 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;

   . . .
}

Une fois l’emplacement défini, vous pouvez tirer parti des variables que Nginx utilise pour chacune de ces bases de données. La base de données au niveau des pays nous donne accès aux variables suivantes:

  • * + $ geoip_country_code + *: code de pays à deux lettres utilisé pour représenter un pays. Par exemple, «US» pour les États-Unis ou «RU» pour la Russie. Ceux-ci peuvent être trouvés here.

  • * `+ $ geoip_country_code3 + + *: presque les mêmes que ci-dessus, mais en utilisant la variante à trois lettres. Par exemple, "USA" ou "RUS".

  • * + $ geoip_country_name + *: nom attribué au code du pays, comme indiqué dans la liste liée. Par exemple, «Nouvelle-Zélande» pour «NZ».

La base de données au niveau de la ville nous fournit un plus grand nombre de variables. Avec cette base de données, nous avons accès à:

  • * + $ geoip_area_code + *: Un champ d’indicatif régional hérité pour les numéros de téléphone américains. Cela ne devrait pas être invoqué pour des données précises.

  • * + $ geoip_city_continent_code + *: code de continent à deux lettres.

  • * + $ geoip_city_country_code + *: Le même code de pays à deux lettres fourni par la base de données au niveau du pays.

  • * + $ geoip_city_country_code3 + *: Le même code de pays à trois lettres fourni par la base de données au niveau du pays.

  • * + $ geoip_city_country_name + *: même nom de pays que celui fourni par la base de données nationale.

  • * + $ geoip_dma_code + *: code de région ou de métro DMA pour les emplacements situés aux États-Unis. Vous le trouverez dans l’API AdWords de Google, à l’adresse here.

  • * + $ geoip_latitude + *: estimation de la latitude de l’IP d’origine.

  • * + $ geoip_longitude + *: estimation de la longitude de l’IP d’origine.

  • * + $ geoip_region + *: Code de région à deux caractères utilisé pour représenter une région politique, telle qu’un territoire, un État, une province, etc.

  • * + $ geoip_region_name + *: nom complet associé au code de région ci-dessus.

  • * + $ geoip_city + *: nom de la ville associé à l’IP d’origine.

  • * + $ geoip_postal_code + *: Le code postal de la région où se trouve l’IP.

Encore une fois, il est important de souligner que les données disponibles au moyen de ces variables sont basées sur des hypothèses. Même dans ce cas, cela nous offre de grandes opportunités de proposer différents contenus dans différents domaines.

Nous utiliserons souvent l’une des variables ci-dessus avec la directive + map + pour définir la valeur d’une autre variable de manière conditionnelle. Cela nous permet de créer une variable avec une valeur déterminée par ce que la base de données nous dit sur l’emplacement du client.

La directive + map + devrait également être utilisée dans le contexte + http +. Par exemple, nous pouvons configurer notre site pour afficher un contenu différent si le visiteur vient de l’Australie ou de Singapour. La meilleure façon de vérifier cela consiste probablement à utiliser l’un des codes de pays à deux ou trois lettres trouvés dans les bases de données du pays ou de la ville.

Nous allons utiliser le + $ geoip_country_code + pour cet exemple. La valeur de cette variable déterminera ce que nous stockons dans la variable + $ site_version + que nous créons. Nous allons l’utiliser pour déterminer la racine du document à partir de laquelle servir:

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";
   }

   . . .
}

Ceci définit la valeur de + $ site_version +, une variable que nous créons spécifiquement à cette fin. Si le code pays du visiteur indique qu’il vient d’Australie (+ AU +), nous allons définir + $ site_version + sur «/ australia». Si le visiteur est originaire de Singapour («SG»), nous allons définir + $ site_version + sur «/ singapore». Si leur code pays indique une autre valeur, nous allons définir le + $ site_version + sur une chaîne vide.

Cela nous permet de modifier la racine du document pour nos visiteurs de pays spécifiques. Il s’agit d’un choix arbitraire pour illustrer une méthode permettant de différencier le contenu en fonction des données de géolocalisation du client.

Pour modifier la racine du document, il suffirait de définir la directive + root + dans le bloc de serveur comme suit:

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 {
       . . .



       . . .

   }
}

Si l’utilisateur est originaire d’Australie, la racine du document pour les demandes de service sera remplacée par + / usr / share / nginx / html / australia +. De même, pour les visiteurs de Singapour, le contenu sera servi à partir de + / usr / share / nginx / html / singapore +. Pour les autres visiteurs, la variable + $ site_version + a été définie sur une chaîne vide. Ils continueront donc à recevoir du contenu provenant de + / usr / share / nginx / html +.

Nous pouvons configurer la racine du document + / usr / share / nginx / html + par défaut pour le tester facilement. Commencez par vous déplacer à cet endroit:

cd /usr/share/nginx/html

Ensuite, nous pouvons créer les répertoires que nous avons mentionnés et insérer du contenu très basique dans un fichier + index.html + dans chacun des nouveaux répertoires. Cela nous permettra de voir si notre emplacement a un impact sur le contenu qui nous est fourni:

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

Une fois tout cela configuré, nous pouvons tester notre configuration et recharger Nginx:

sudo nginx -t
sudo service nginx restart

Nous pouvons maintenant profiter à nouveau du site GeoPeeker pour voir si nous recevons un contenu différent provenant de lieux différents. L’Australie et Singapour sont des options que le site vous permet de vérifier.

Ici, vous pouvez voir la page par défaut pour un visiteur venant des États-Unis ou d’Irlande, ainsi que le texte de test que nous avons ajouté pour les visiteurs d’Australie ou de Singapour:

image: https: //assets.digitalocean.com/articles/nginx_testing/geo_differences.png [Différences de géolocalisation]

Cela confirme que Nginx sélectionne correctement le contenu à servir en vérifiant l’adresse IP du client par rapport à la base de données de localisation.

Conclusion

En tirant parti de ces stratégies et capacités, vous pouvez commencer à rassembler des analyses pour vous aider à prendre des décisions plus éclairées concernant le contenu de votre site. Bien qu’il existe certainement de nombreux outils externes disponibles pour capturer ce type de données, l’option d’utiliser les outils natifs de Nginx peut être un bon choix avant d’investir du temps dans d’autres solutions.