开发者学堂课程【大数据分析之企业级网站流量运营分析系统开发实战(第一阶段):网站流量日志埋点收集—后端脚本(nginx+lua)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/693/detail/12177
网站流量日志埋点收集—后端脚本(nginx+lua)
内容简介
一、后端服务器 nginx 相关知识学习
二、后端代码逻辑的梳理
三、小结
当我们的前端,通过各种埋点代码,JS 自调用,并把我们的数据收集到,并且拼接成我们图片的参数发送给后端的时候,作为后端的服务器脚本,所做之事将会非常重要,怎么样去解析请求我们这些参数,把参数解析下来保存在日志当中,并且给它响应一个所谓的一乘以一像素的图片,给它响应 cookie,那么这些支持都是作为后端需要完成的,那么本节内容我们学习后端脚本的实现逻辑。
一、后端服务器 nginx 相关知识学习
由图知,我们后端服务器是使用 nginx 来做处理,而且是一个特殊版的 nginx,要想了解特殊在哪我们先了解 nginx 本身是一个高性能的web服务器,是用C语言编写的,做web服务和反向代理等都非常方便,但它本身的配置逻辑,配置文件和表达应用逻辑比较吃力。
所以市面上有很多针对 nginx 高性能做的一些扩展平台,当中最著名的是 OpenResty。OpenResty 相当于一个插件平台,基于nginx可以开发出各种各样高性能的插件,用来做网络的 web 应用服务。当中有一个最著名的插件叫做ngx_lua,lua 是一个嵌入式的脚本语言,是用标准的 c 语言开发写的。
当我们的 nginx 和 lua 做集成之后,就可以在 nginx 配置中使用 lua 语言去编写相关的逻辑。
在这里需要强调不管是 lua 语言还是 nginx 语言,我们并未学过,所以在我们的后端逻辑我们就要理清作为后端我们到底要做什么事情。整个后端核心的重点是 nginx 配置文件,当中的重点模块是 location 模块,location 在 nginx 当中通常用于我们请求资源的匹配。
二、后端代码逻辑的梳理
后端局部放大图:
后端为 collect.itcasrt.cn,由 nginx(基于lua)搭建
整个当中的重点是 location 模块,location 在 nginx当中通常用于我们请求资源的匹配,由匹配上的模块是处理对应的请求。
首先看第一个模块:location/log.gif
我们前端发送数据的名字都叫 log.gif,即所有前端发送叫做 log.gif将会由这台服务器进行处理。因为我们发送的请求叫做collect.itcast.cn/log.gif?item=001&name=allen,这个请求中我们请求的资源是 log.gif,而 location 模块也是 log.gif,所以将会由对应的location模块来处理相应的请求。不管 location 模块用什么语言去实现它的目标都是解析参数,梳理请求,响应图片和响应cookie。到底如何操作我们要回到代码中梳理。
代码为:
#伪装成gif文件
Default_type image/gif;
#本身关闭 access_ log,通过 subrequest 记录 log
Access_1og off;
access_ by_ lua ”
-用户跟踪 cookie 名为_ utrace
local uid = ngx. var. cookie __utrace
if not uid then
-- 如果没有则生成-一个跟踪cookie, 算法为
md5 (时间戳+IP+客户端信息)
uid = ngx. md5 (ngx. now() . .
ngx. var. remote addr .. ngx. var. http_ user_ agent)
end
ngx. header[' Set-Cookie' ] = {’_ utrace=’ .. uid ..
’; path=/'}
if ngx. var. arg domain then
--通过 subrequest 子请求到/i-log 记录日志,
将参数和用户跟踪 cookie 带过去
ngx. location. capture(' /i-log? ‘..
ngx. var. args ..’&utrace=' .. uid).
end
”;
#此请求资源本地不缓存
add_ header Expires "Fri, 01 Jan 1980 00:00:00 GMT" ;
add _header Pragma ''no-cache" ;
add_ header Cache- Control " no- cache,max -rage=0,must-
revalidate" ;
#返回一个1X1的空 gif 图片
empty gif;
}
location /i-log {
#内部 location,不允许外部直接访问
internal;.
#设置变量,注意需要 unescape,来自 ngx_ set_misc 模块
set_unescape_uri $u_domain $arg domain;
set_unescape_uri $u_url $arg_url;
set_unescape_uri $u_title $arg_title;
set_unescape_uri $u_ referrer Sarg_referrer;
set_unescape-uri $u_sh $arg_ sh;
首先是伪装成gif文件,这是 lua 语法。再是用 lua 语言生成一个 cookie,我们知道 cookie 叫做浏览器端,客户端用户的唯一标识,它里面的要求是 cookie 的 key,cookie 的 value,cookie 的 path 和 cookie 的过去时间,当中最重要的是 cookie 的id。因为 cookie 作为用户的生成标识,最大要求就是 cookie 的 id不能重复。
在这里它通过什么保证生成的 cookie 不重复?这里 cookie的key是__utrace,如果它不存在,用 lua 语法解读,先获取当前的系统时间:ngx.now(),再获取用户的id信息 var. remote addr,再获取用户的终端信息http_ user_ agent,以上三个属性调用 md5 加密生成唯一的特征值。这种算法基本可以避免 cookie 的重复,比如我们通过这种算法生成了 cookie的key,value 是通过算法生成,然后设置 ngx. header[' Set-Cookie' ] = {’_ utrace=’ .. uid .. 在响应图中,路径是在我们的根路径下返回给我们的客户端。在这里生成 cookie 后并没有解析我们的参数,而是做了一个 subrequest 子跳转,跳转至/i=log?的location中 。
我们发现代码底下还有 location /i-log {。所以如图,右侧也有 location /i-log {。
左侧 location /i-log { 功能为生成 cookie 和响应图片,之后它并未解析参数而是携带参数内部子跳转 subrequest。跳转之后设置了资源不缓存,用 lua 语言返回了一个空图片。右侧功能是解析参数和接受请求,它是内部 internal location,意味着这样的模块外部无法直接请求访问,必须通过内部 location 跳转才能访问。
使用 lua 语法对参数进行解析:set_unescape_uri 是固定搭配,$后的 domin,arg 等是指根据这个值去解析参数,通过第二个$后面的变量截取 url 的参数,然后复制给第一个$的变量,就是等下需要保存的变量 u_,u 表示自定义变量,所以这个语法使用了非常棒的插件。即 set_unescape_uri $u_domain $arg domain; 中,$arg domain 用来解析参数,然后复制给 $u_domain,然后这个变量写在 log.files 中保存数据。通过 ngx_lua 语法就完成了数据解析工作。
带有 u 开头的表示我们自定义的属性,不带有就是 nginx 默认的属性,然后把参数保存下来定义格式就可以写在日志中。
当然有请求就要有响应,如果请求图片就要 response log.gif 1*1 。以上就是后端的整体逻辑。
三、小结
这个过程我们使用的是 ngx_lua 语法,我们没有学过,里面的代码语言不要求掌握,但是逻辑根据注释要梳理清楚。
小结:
●后端脚本
所谓后端就是接受解析前端发送采集数据的服务器
1.接受请求 解析参数 保存数据
2.响应图片 log.gif 1*1
3.响应 cookie cookiekey cookievalue path
注意搞清楚 nginx中location 模块的具体职责:用于请求 url 资源路径的匹配。