介绍
Nginx是一个强大的代理和Web服务器,被一些最大的网站用来处理客户端连接和服务内容。虽然大多数用户熟悉Nginx的基本功能,但是有其他功能,在典型的使用中可能不是很明显。 在本指南中,我们将探讨一组可帮助测试新内容和收集用户统计信息的功能。这些对于内容开发目的,简单的A / B测试以及频繁访问您网站的不同用户组的行为都非常有用。 Nginx有能力轻松地将这些功能合并到Web服务器本身。
使用拆分客户端模块进行简单A / B测试
我们将首先展示如何通过Nginx本身配置一些基本的A / B测试。 我们可以称之为一个标准的HTTP模块做
http_split_clients
。除非在自定义编译期间显式禁用,否则这应该在任何标准Nginx安装中可用。 该模块提供了一个名为勿庸置疑的单一指令,
split_clients
这样会将连接请求到基于配置的要求两个或多个类别。 该指令在定义
http
的背景下,任何服务器块之外。它指定要在每个连接中检查的值,并创建一个用于存储结果的变量。 该指令的基本语法看起来像这样:
http {
. . .
split_clients "variable_to_evaluate" $new_variable {
percent_group% value_to_store;
percent_group% value_to_store;
}
}
该指令通过内插传递的第一个变量的值并散列结果来工作。相同的值将始终产生相同的散列,允许一致的结果。被检查的变量在求值时必须产生一个字符串。 在内部的线
split_clients
块表示这是由他们应该消耗完可用的哈希空间的百分比定义的各种“桶”或替代方案。 这创建了散列“范围”,其匹配由所提供的百分比确定的一定数量的散列。 每个都定义一个值,当哈希值在该桶的范围内时,应该设置该值。 的过程中给定的第二可变
split_clients
定义被设置为这个值。 当考虑一个例子时,这更容易理解。看看下面的块:
split_clients "${remote_addr}" $designtest {
10% ".first";
10% ".second";
* "";
}
在上面的例子中,我们评估该连接的价值
$remote_addr
,其通过Nginx的设置客户端的IP地址。客户端的IP地址的值使用murmurhash2散列算法进行散列。此时,Nginx检查计算的哈希值落在哪个哈希范围内。由于Nginx采用的murmurhash2实现使用32位,哈希值将在0到4294967295(最高的32位数)之间。 由于第一个组定义了总散列的10%,这将匹配从0到429496729,这是可用范围的前十分之一。产生在该范围内的散列值也将设置
$designtest
变量的“。首先”的值。 带有从大约429496730到858993459的散列的IP地址,由接下来的10%可用散列表示的散列范围将匹配第二行。在这些情况下,
$designtest
变量将被设置为“。第二”。 对于所有其他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配置进行上述更改并重新启动Web服务器,则可以对其进行测试。我们可以检查我们的配置文件没有语法错误,然后通过键入以重新启动服务:
sudo nginx -t
sudo service nginx restart
如果我们在浏览器中访问该网站,我们将看到上面的三个文件之一。很可能,它将是最后一个,因为它将提供给80%的网站访问者。如果您想了解如何为其他用户显示,您可以通过代理服务器或使用一些网络工具访问该网站。 例如,
GeoPeeker网站可用于来自世界各地不同的位置查看您的网站。如果您输入了您的域名,您可能会看到至少一个您的替代网站:
另一个类似的网站是
LocaBrowser ,它允许您从不同国家的选择。请注意,正在投放的网页的划分不是基于地理位置,而是基于IP地址的哈希,因此并不意味着来自一个国家/地区的所有访问者都将投放同一个文件。 虽然上面的例子是一个简单的例子,这个概念可以扩展相当多。您可以使用该设置变量
split_clients
指令来设置cookies和用户ID,通过头部到后端代理等。如果您想A / B测试更彻底,你不妨使用变量设置确定文档根服务于不同方。 同样重要的是要记住,
${remote_addr}
检查仅仅是一个很好的例子。 你可以基于任何Nginx的变量的值在字符串中工作的哈希。 你可以找到那些包含在核心模块的列表
在这里 ,虽然其他变量都可以通过其他模块。有关详细信息,请参阅文档。
使用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
从内存。 我们告诉这个位置的请求,使用我们之前指定的格式登录到一个单独的文件。 最后,我们设置过期为“时代”,它应告知浏览器不要缓存
.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
:用来代表一个国家的两个字母的国家代码。 例如,美国为“US”,俄罗斯为“RU”。 这些都可以找到这里 。
$geoip_country_code3
:几乎相同以上,但使用三字母变体。例如,“USA”或“RUS”。
$geoip_country_name
:如图链表映射到国家代码的名称。例如“新西兰”为“新西兰”。
城市级数据库为我们提供了更多的变量。使用该数据库,我们可以访问:
$geoip_area_code
:美国的电话号码上的遗留区号领域。这不应依赖于准确的数据。
$geoip_city_continent_code
:双字母洲代号。
$geoip_city_country_code
:由国家一级数据库提供的相同的两个字母的国家代码。
$geoip_city_country_code3
:由国家一级数据库提供的相同的三个字母的国家代码。
$geoip_city_country_name
:由国家一级数据库提供的同一个国家的名字。
$geoip_dma_code
:DMA的区域或地铁代码为美国的位置。 这可以在谷歌的AdWords API的,发现找到这里 。
$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
为“/澳大利亚”。 如果游客是来自新加坡(“SG”),我们将设置
$site_version
为“/新加坡”。 如果他们的国家代码指示其他任何价值,我们将设置
$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 {
. . .
root /usr/share/nginx/html${site_version};
. . .
}
}
如果用户是从澳大利亚,文档根目录服务请求将被改为
/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再次现场看到,如果我们从不同的地点提供不同的内容。澳大利亚和新加坡都是网站允许您检查的选项。 在这里,您可以查看来自美国或爱尔兰的访问者的默认页面,以及我们为来自澳大利亚或新加坡的用户添加的测试文字:
这验证了Nginx正在通过根据位置数据库检查客户端的IP地址来正确地选择要提供的内容。
结论
通过利用这些策略和功能,您可以开始收集分析数据,帮助您对自己的网站内容做出更明智的决策。虽然肯定有许多外部工具可用于捕获这种类型的数据,但是在将时间投入其他解决方案之前,可以选择使用Nginx本地工具是一个不错的选择。