前言

Google Analytics 加载缓慢是本博客在国内访问缓慢的原因之一。虽然通过使用大公司的 ga.js 的 CDN ,可以很大程度上加快加载 ga.js 文件的速度( ga.js 的更新频率很高,并不适合缓存到本地或服务器,所以最好自己反代或者借大公司的光,参见 谷歌分析(Google Analytics) 加速实现秒加载页面 ),但无论如何还是要向 Google 发送一个请求来发送访客数据,所以取巧地使用 CDN 并不能从根本上解决问题。前段时间翻看一个知名博主的文章时,有一篇名为 本博客零散优化点汇总 的文章中写道:「通过服务器端异步发送统计数据的方式来解决这个问题」,这的确是个经济实惠的办法,下面就来实践一下。

思路

  • 方案一:通过 Nginx 的 proxy ,根据 官方给出的文档 向 Google 转发访客数据。
  • 方案二:设立中转服务器,在客户端通过 JS 发送异步请求给中转服务器,由中转服务器将访客信息发送给 Google。

这两种方法都切实可行,不过也都有一个大前提,那就是服务器(中转服务器)必须设置于境外,能够顺畅地访问 Google Analytics ,否则做的也不过是无用功。本文选择较为简单但是定制性不是很强的第一种方案,第二种方案可以参考这篇博文及博主开源的项目:服务端使用 Google Analytics

建立访客 ID

如果我们查看使用 Google Analytics 服务的网站,我们总会在看到一个 _ga 的 cookie 。实际上, ga.js 将此 cookie 中的值做处理后作为本次访问访客的 uid 传回 Google 的服务器,Google Analytics 根据这个 uid 进行访客行为的追踪和新旧访客的统计,这也是官方文档中 cid 参数的作用所在。

因此我们必须针对每一个用户手动生成一个 uid 发送给 Google ,同时也要将这个 uid 保存在客户端的 cookie 中,从而实现在每次访问中,通过判断该 cookie 是否为空来决定是否生成新的 uid 。

本文借助 Nginx 的 userid 模块,便可很轻松的实现这一功能。不过如果想要实现更完善的 uid 生成,还是手写模块或者写 lua 脚本比较好。在 nginx 配置文件中添加如下内容来开启 userid 模块:

    userid on;
userid_name cid;
userid_domain easonyang.com;
userid_path /;
userid_expires max;

建立 tracker location

要想使用 Nginx 发送异步请求,就要活用 nginx 的「 proxy 」和「 location 内部 redirect 匹配」两大功能。这一节内容部分借鉴于 Ng­inx 内配置 Google An­a­lyt­ics 指南 一文。

我们知道「 location 内部 redirect 匹配」的写法是这样的:

location @tracker {
}

所以,我们只要在上面这个 location 块中添加 proxy_pass 就可以了。此处需要注意的是,如果按照上文提到的那篇文章进行配置,我们会发现在大部分情况下转发总是不成功,经过研究,这种情况下必须要加上一个能解析 Google 的 DNS 才可以成功转发。这里直接使用经典的 8.8.8.8 及其 IPV6 地址,最后 location 块为:

location @tracker {
internal;
resolver 8.8.8.8 [2001:4860:4860::8888];
proxy_method GET;
proxy_pass https://www.google-analytics.com/collect?v=1&tid=UA-11111111-1&$uid_set$uid_got&t=pageview&dh=$host&dp=$uri&uip=$remote_addr&dr=$http_referer&z=$msec;
proxy_set_header User-Agent $http_user_agent;
proxy_pass_request_headers off;
proxy_pass_request_body off;
}

使用 tracker location

最后只要在控制网站访问的 location 块中加上 post_action @tracker; 就大功告成了。示例:

    location / {
root /var/www/hexo;
post_action @tracker;
}

然而在实际使用中,我们会发现这样配置使得在 Google Analytics 中看到的网站访问量大大增加,这似乎不像是绕过 Adblock 这样插件而实现的效果。实际上,这是源于在上文的配置中,Nginx 直接把各种搜索引擎蜘蛛也当作普通访客发送给 Google Analytics 的缘故。因此还要将 Spider 过滤掉:

    location / {
root /var/www/hexo;
if ($http_user_agent !~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|YiSou Spider") {
post_action @tracker;
}
}

为 Hexo 配置 tracker location

由于本文使用 Hexo 博客系统,所以此处特别说明一下 Hexo 相关的 Nginx 配置。

配置

在为 Hexo 配置 Nginx 时,我们总习惯于将 location 定义为:

    location / {
root /var/www/hexo/easonyang.com/blog; if (-f $request_filename) {
post_action @tracker;
rewrite ^/(.*)$ /$1 break;
}
}

这样一来我们就要进一步定制 hexo 的 location :

    location / {
root /var/www/hexo; set $flag "0"; if (-f $request_filename) {
set $flag "${flag}1";
} if ($http_user_agent !~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|YiSou Spider") {
set $flag "${flag}2";
} if ($flag = "012") {
post_action @tracker;
rewrite ^/(.*)$ /$1 break;
} if ($flag = "01") {
rewrite ^/(.*)$ /$1 break;
}
}

说明

If is devil.

这是 Nginx 的使用者都知道的至理名言,此处逻辑比较简单,就直接用 if 了。非常不喜欢 if 的话就用 map 代替下吧。

测试

暂时将 proxy_pass https://www.google-analytics.com/collect?v=1&tid=UA-11111111-1&$uid_set$uid_got&t=pageview&dh=$host&dp=$uri&uip=$remote_addr&dr=$http_referer&z=$msec; 修改为 proxy_pass https://127.0.0.1:9999/collect?v=1&tid=UA-11111111-1&$uid_set$uid_got&t=pageview&dh=$host&dp=$uri&uip=$remote_addr&dr=$http_referer&z=$msec; ,然后在服务器上运行命令:

 nc -k -l 0.0.0.0 9999

监听 9999 端口,最后访问网站,就可以在服务器上查看到请求的相应信息。

关于更进一步的请求过滤

虽然我们可以通过设定更加复杂的 Nginx 配置,来实现过滤特定请求进而避免这些无用数据如 404 页面被发往 Google Analytics 的情况发生,但我们完全可以使用更加方便、高效的 Google Analytics 过滤器来满足各种过滤需求,详细配置参见 Google 的官方文档:

博客链接:https://easonyang.com/2016/11/04/google-analytics-via-nginx/

关注公众号「举一得一」获取最新文章更新

使用Nginx将请求转发至Google Analytics实现后端数据统计的更多相关文章

  1. nginx实现请求转发

    反向代理适用于很多场合,负载均衡是最普遍的用法. nginx 作为目前最流行的web服务器之一,可以很方便地实现反向代理. nginx 反向代理官方文档: NGINX REVERSE PROXY 当在 ...

  2. Nginx的简介和使用nginx实现请求转发

    一.什么是Nginx Nginx是lgor Sysoev为俄罗斯访问量第二的rambler.ru站点设计开发的.从2004年发布至今,凭借开源的力量,已经接近成熟与完善. Nginx功能丰富,可作为H ...

  3. Nginx配置请求转发location及rewrite规则

    一个示例: location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 因为所有的地址都以 / 开头,所以这 ...

  4. nginx得请求转发代码-将请求转发到网关

    首先:本地主机host更改成 192.168.111.1 gulimail.com 这样一访问网址就能映射到本地. 然后修改nginx得conf worker_processes 1; events ...

  5. window10安装nginx及请求转发到tomcat服务器访问项目及开机自启

    一.安装ngnix 1.  到nginx官网上下载相应的安装包,http://nginx.org/en/download.html: 下载进行解压,将解压后的文件放到自己心仪的目录下,我的解压文件放在 ...

  6. nginx实现请求的负载均衡 + keepalived实现nginx的高可用

    前言 使用集群是网站解决高并发.海量数据问题的常用手段.当一台服务器的处理能力.存储空间不足时,不要企图去换更强大的服务器,对大型网站而言,不管多么强大的服务器,都满足不了网站持续增长的业务需求.这种 ...

  7. 【转载】国内网站博客数据统计选免费Google Analytics还是百度统计

    [转载]国内网站博客数据统计选免费Google Analytics还是百度统计 Google Analytics谷歌统计是我用的第一个网站统计工具,当然现在也一直在用.Google Analytics ...

  8. 微信内嵌浏览器sessionid丢失问题,nginx ip_hash将所有请求转发到一台机器

    现象微信中打开网页,图形验证码填写后,经常提示错误,即使填写正确也会提示错误,并且是间歇性出现. 系统前期,用户使用主要集中在pc浏览器中,一直没有出现这样的问题.近期有部分用户是在微信中访问的,才出 ...

  9. nginx学习(2):启动gzip、虚拟主机、请求转发、负载均衡

    一.启用gzip gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 2; ...

随机推荐

  1. Redis集群最佳实践

    今天我们来聊一聊Redis集群.先看看集群的特点,我对它的理解是要需要同时满足高可用性以及可扩展性,即任何时候对外的接口都要是基本可用的并具备一定的灾备能力,同时节点的数量能够根据业务量级的大小动态的 ...

  2. ubuntu下网络IP设置相关命令

    一.使用命令设置ubuntu的ip地址 1.修改配置文件blacklist.conf禁用IPV6: sudo vi /etc/modprobe.d/blacklist.conf 2.在文档最后添加 b ...

  3. 无需activity获得屏幕尺寸

    原文地址:http://blog.sina.com.cn/s/blog_4c277ad30100yfqo.html 客户需求需要增加对手机尺寸的读取 于是找了两个方法 第一种:通过activity引用 ...

  4. Svn + tomcat + Hudson持续集成部署

    1.首先下载hudson 2. 我这里使用hudson-3.0.1版本 3. 下载后hudson是一个 war 包 4. 操作部署: (1). 直接将hudson的war包复制到tomcat的weba ...

  5. GitHub上删除项目

    1. 在自己的repositories中,选择要删除的项目,左击. 2.  选择 [Settings] 3.  选择 [Delete ** ] 4.  在弹出框中 输入 要删除的项目名,点击下方的按钮 ...

  6. Spring Boot集成Jasypt安全框架

    Jasypt安全框架提供了Spring的集成,主要是实现 PlaceholderConfigurerSupport类或者其子类. 在Sring 3.1之后,则推荐使用PropertySourcesPl ...

  7. 项目开发经常使用PHP功能

    日期操作 为了便于存储.比较和交付.我们通常使用strtotime()功能转换的日期UNIX时间戳.有仅用于在显示给用户时date()成经常使用的时间格式. strtotime()  函数将不论什么英 ...

  8. Linux 上 C 程序的内存布局

    在仔细研究这个问题之前,我认为 C 程序在内存中只有代码段,堆和栈三部分构成.前几天面试被问到了这个问题,才发现自己的印象是不完全的. 在本文中通过解析析一个 C 程序中变量和函数的地址来分析 C 程 ...

  9. Unity3D学习笔记(一)GUI控件的调用

    GUI控件:1.在Start中初始化,在OnGUI中调整.2.公有变量才会出现在Inspector面板.3.GUI控件的初始化和处理在OnGUI内完成.4.JavaScript的中文为UTF-8编码可 ...

  10. luogu P5303 [GXOI/GZOI2019]逼死强迫症

    传送门 只有两行,考虑递推,设\(f_i\)为没有那两个\(1*1\)的,前\(i\)列的方案,可以发现一次可以放一个竖的或两个横的,也就是\(f_i=f_{i-1}+f_{i-2}\) 再设\(g_ ...