前書き

Nginxは、クライアント接続を処理し、コンテンツを提供するために最大規模のサイトで利用されている強力なプロキシおよびWebサーバーです。 ほとんどのユーザーはNginxの基本機能に精通していますが、他の機能は通常の使用法ではすぐに明らかにならない場合があります。

このガイドでは、新しいコンテンツをテストし、ユーザーに関する統計を収集するのに役立つ一連の機能について説明します。 これらは、コンテンツ開発の目的、簡単なA / Bテストの実行、サイトに頻繁にアクセスするさまざまなユーザーグループの動作の把握に非常に役立ちます。 Nginxには、これらの機能をWebサーバー自体に簡単に組み込む機能があります。

Split Clientsモジュールを使用した簡単なA / Bテスト

まず、Nginx自体を使用して基本的なA / Bテストを構成する方法を紹介します。 `+ http_split_clients +`と呼ばれる標準のHTTPモジュールでこれを行うことができます。 カスタムコンパイル中に明示的に無効にしない限り、これは標準のNginxインストールで利用できるはずです。

モジュールは、構成された要件に基づいて接続要求を2つ以上のカテゴリに分割する「+ split_clients 」という当然のことながら、単一のディレクティブを提供します。 このディレクティブは、サーバーブロックの外部の ` http +`コンテキストで定義されます。 各接続で確認する値を指定し、結果を保存する変数を作成します。

ディレクティブの基本的な構文は次のようになります。

http {

   . . .

   split_clients "" $ {
       %        ;
       %        ;
   }

}

ディレクティブは、渡された最初の変数の値を補間し、結果をハッシュすることにより機能します。 同じ値は常に同じハッシュを生成し、一貫した結果を可能にします。 チェックされる変数は、評価時に文字列を生成する必要があります。

`+ split_clients `ブロック内の行は、利用可能なハッシュスペースを消費する割合で定義されるさまざまな「バケット」または代替を表します。 これにより、指定された割合で決定される特定の数のハッシュに一致するハッシュ「範囲」が作成されます。 これらはそれぞれ、ハッシュがそのバケットの範囲内にあるときに設定される値を定義します。 ` split_clients +`の定義中に指定された2番目の変数は、この値に設定されます。

これは、例を検討するときに理解するのがはるかに簡単です。 次のブロックを見てください。

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

上記の例では、NginxによってクライアントのIPアドレスに設定されている `+ $ remote_addr +`の接続の値を評価しています。 クライアントのIPアドレスの値は、murmurhash2ハッシュアルゴリズムを使用してハッシュされます。 この時点で、Nginxは計算されたハッシュがどのハッシュ範囲内にあるかをチェックします。 Nginxが採用しているmurmurhash2実装は32ビットを使用しているため、ハッシュは0〜4294967295(最高の32ビット数)の間になります。

定義された最初のグループはハッシュの合計の10%を指定するため、これは0から429496729に一致します。これは、使用可能な範囲の最初の10分の1です。 この範囲内でハッシュを生成する値は、 `+ $ designtest +`変数を“ .first”の値に設定します。

ハッシュが約429496730〜858993459のIPアドレス(利用可能なハッシュの次の10%で表されるハッシュ範囲)は、2行目に一致します。 これらの場合、 `+ $ 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 `というファイルを提供しようとします。 同様に、2番目のグループに分類されるIPアドレスの場合、Nginxは ` index.second.html `というファイルを探します。 IPアドレスが3番目のグループにある場合、 ` $ designtest `変数は空の文字列に設定されるため、従来の ` index.html +`ファイルが提供されます。

ここで、ドキュメントルートに3つのインデックスファイルを作成すると、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設定に上記の変更を加えてWebサーバーを再起動する場合、これをテストできます。 構成ファイルに構文エラーがないことを確認し、次のように入力してサービスを再起動します。

sudo nginx -t
sudo service nginx restart

ブラウザでサイトにアクセスすると、上記の3つのファイルのいずれかが表示されます。 おそらく、それはサイト訪問者の80%に配信されるため、最後のものになります。 他のユーザーにどのように表示されるかを確認したい場合は、プロキシサーバーまたはWebツールを使用してサイトにアクセスできます。

たとえば、https://geopeeker.com/ [GeoPeeker]サイトを使用して、世界中のさまざまな場所からサイトを表示できます。 ドメイン名を入力すると、少なくとも1つの代替サイトが表示される場合があります。

image:https://assets.digitalocean.com/articles/nginx_testing/ab_testing.png [代替サイトインデックス]

別の同様のサイトはhttp://www.locabrowser.com/[LocaBrowser]で、さまざまな国から選択できます。 提供されるページの分割は、位置情報ではなくIPアドレスのハッシュに基づいているため、ある国からのすべての訪問者に同じファイルが提供されるわけではないことに注意してください。

上記の例は単純な例ですが、概念は非常に多く拡張できます。 `+ split_clients +`ディレクティブによって設定された変数を使用して、CookieとユーザーIDを設定したり、ヘッダーをバックエンドプロキシに渡したりすることができます。 A / Bテストをより完全に行いたい場合は、設定した変数を使用して、さまざまな関係者に提供されるドキュメントルートを決定できます。

また、 `+ $ {remote_addr} +`チェックは単なる有用な例であることを忘れないでください。 文字列で機能するNginxの変数の値に基づいてハッシュできます。 他の変数は他のモジュールから入手できますが、コアモジュールに含まれているもののリストはhttp://nginx.org/en/docs/http/ngx_http_core_module.html#variables [こちら]にあります。 詳細については、ドキュメントを確認してください。

empty_gifディレクティブを使用したトラッキングピクセルの設定

管理者がサイトにアクセスしたユーザーを説明する方法の1つは、トラッキングピクセルを使用することです。 トラッキングピクセルは、管理者が単純なログ記録を介して、どの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;
       }
   }
}

ここでは、追跡したい情報を記録するために、「+ http 」コンテキストで「 log_format +」を設定します。 これは何でも構いません。

その後、特定の `+ .gif `リクエストに一致するようにロケーションブロックを設定できます。 ` = `修飾子を使用しているので、他の場所でより良い一致を検索することなく、 ` .gif `に対する要求が迅速かつ効率的に一致します。 任意の ` .gif +`名を選択できます。

内部では、 `+ empty_gif `ディレクティブを使用して、メモリから透明な1×1ピクセルの ` .gif `を提供します。 前に指定した形式を使用して、この場所への要求に別のファイルにログを記録するように指示します。 最後に、有効期限を「エポック」に設定します。これにより、ブラウザに「 .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 +`を微調整し、テキスト処理ツールを使用してログを解析することにより、より洗練されたシステムに構築できます。

地理に基づいたコンテンツの差別化

前に、 `+ split_clients +`モジュールを使用したA / Bテストのために、ユーザーを自動的にグループに分割するようにNginxを設定する方法を示しました。 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に伝えることができます。 これらは、Nginx設定ファイルの `+ http +`コンテキストで設定する必要があります。

. . .

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 + *:国を表すために使用される2文字の国コード。 たとえば、米国の場合は「US」、ロシアの場合は「RU」です。 これらはhttp://dev.maxmind.com/geoip/legacy/codes/iso3166/ [こちら]にあります。

  • * + $ geoip_country_code3 + *:上記とほぼ同じですが、3文字のバリアントを使用します。 たとえば、「USA」または「RUS」。

  • * + $ geoip_country_name + *:リンクリストに表示される国コードにマップされた名前。 たとえば、「NZ」の場合は「ニュージーランド」。

都市レベルのデータベースは、より多くの変数を提供します。 そのデータベースを使用して、次の情報にアクセスできます。

  • * + $ geoip_area_code + *:米国の電話番号の従来の市外局番フィールド。 正確なデータを得るためにこれに頼るべきではありません。

  • * + $ geoip_city_continent_code + *:2文字の大陸コード。

  • * + $ geoip_city_country_code + *:国レベルのデータベースによって提供される同じ2文字の国コード。

  • * + $ geoip_city_country_code3 + *:国レベルのデータベースによって提供される同じ3文字の国コード。

  • * + $ geoip_city_country_name + *:国レベルのデータベースで提供されるものと同じ国名。

  • * + $ geoip_dma_code + *:米国の場所のDMA地域または大都市圏コード。 これは、https://developers.google.com/adwords/api/docs/appendix/cities-DMAregions [こちら]にあるGoogleのAdWords APIにあります。

  • * + $ geoip_latitude + *:発信元IPの緯度の推定値。

  • * + $ geoip_longitude + *:発信元IPの経度の推定値。

  • * + $ geoip_region + *:領土、州、県などの政治地域を表すために使用される2文字の地域コード。

  • * + $ geoip_region_name + *:上記の地域コードに関連付けられたフルネーム。

  • * + $ geoip_city + *:発信元IPに関連付けられた都市名。

  • * + $ geoip_postal_code + *:IPが配置されている地域の郵便番号。

繰り返しますが、これらの変数を介して利用可能なデータは、最良の推測に基づいていることを強調することが重要です。 それでも、これにより、さまざまなコンテンツをさまざまな分野に提供する素晴らしい機会が得られます。

多くの場合、上記の変数の1つを `+ map +`ディレクティブとともに使用して、別の変数の値を条件付きで設定します。 これにより、データベースがクライアントの場所について何を伝えるかによって決定される値を持つ変数を作成できます。

`+ map `ディレクティブは ` http +`コンテキストでも使用する必要があります。 たとえば、訪問者がオーストラリアまたはシンガポールから来た場合、異なるコンテンツを表示するようにサイトを構成できます。 これを確認する最良の方法は、おそらく国または都市のデータベースにある2文字または3文字の国コードのいずれかを使用することです。

この例では、 `+ $ 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 +`を空の文字列に設定します。

これにより、特定の国からの訪問者のドキュメントルートを変更できます。 これは、クライアントの地理的位置データに基づいてコンテンツを区別できる1つの方法を示すための任意の選択です。

ドキュメントルートを変更するには、サーバーブロック内の `+ 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

これで、https://geopeeker.com/ [GeoPeeker]サイトを再度利用して、異なる場所から異なるコンテンツが提供されているかどうかを確認できます。 オーストラリアとシンガポールはどちらも、サイトで確認できるオプションです。

ここでは、米国またはアイルランドからの訪問者のデフォルトページと、オーストラリアまたはシンガポールからの訪問者用に追加したテストテキストを表示できます。

画像:https://assets.digitalocean.com/articles/nginx_testing/geo_differences.png [位置情報の違い]

これにより、クライアントのIPアドレスをロケーションデータベースと照合して、Nginxが配信するコンテンツを正しく選択していることが検証されます。

結論

これらの戦略と機能を活用することで、分析を収集して、サイトのコンテンツに関するより多くの情報に基づいた意思決定を行うことができます。 このタイプのデータをキャプチャするための外部ツールは確かに多数ありますが、他のソリューションに時間をかける前に、Nginxネイティブツールを使用するオプションを選択することをお勧めします。