名词解释
埋点其实就是用于记录用户在页面的一些操作行为。例如,用户访问页面(PV,Page Views)、访问页面用户数量(UV,User Views)、页面停留、按钮点击、文件下载等,这些都属于用户的操作行为。
开发背景
我司之前在处理埋点数据采集时,模式很简单,当用户操作页面控件时,前端监听到操作事件,并根据上下文环境,将事件相关的数据通过接口调用发送至埋点数据采集服务(简称ets服务),ets服务对数据解析处理后,做入库操作。
流程图如下
这种方式其实没毛病,有如下优势:
(1) 开发难度低,前后端开发人员约定好好接口、参数、模型等即可。
(2) 系统部署容易,排查问题难度低。
但是仔细想想,这种模式弊端也很多:
(1) 开发工作量大。例如,这次有个记录用户点击支付按钮的埋点,前端需要在支付的前端代码中插入一段埋点的代码,后端可能也需要改;后面又来了一个记录用户点击加入购物车按钮的埋点,前端又需要在加入购物车代码中插入一段埋点的代码…… 后续,只要有新的埋点需求,前端就得加代码或者改代码。
(2) 前端埋点接口调用过多影响性能。有可能访问一次页面,或者点击一次连接,要调用十几个埋点接口,而这些接口调用的结果,并不是用户所关心的内容。这样频繁的接口调用,对后端服务也构成了压力。
(3) 增加调试成本。每一次新的埋点需求,都需要前后端联调,沟通、参数、模型等,增加了调试时间。
设计目标
针对老的埋点系统的弊端,需要做重构,达成以下目标:
(1) 埋点数据收集自动化、实时收集;
(2) 减少前端开发工作量;
(3) 减少前后端联调工作量;
(4) 减少前端埋点相关代码。
软件、硬件依赖
请求日志记录
Nginx
日志收集程序
Flume
消息中间件
kakfa+zookeeper
后端日志数据处理服务
ets埋点数据采集微服务,采用springcloud stream技术。
缓存
redis
数据仓库
MongoDB
系统流程图
系统逻辑
(1) 客户端发送请求,通过Nginx进行请求转发,Nginx以json格式记录请求参数等信息至access.log;
(2) flume实时监控Nginx日志变化,收集并过滤有用日志,发送至kafka;
(3) ets服务作为消息消费者,监听kafka topic消息,收到消息后,对日志消息解析处理,确定日志数据存储集合;
(4) 解析token获取用户信息;
(5) 将转化好的日志数据入库。
系统说明
用户的大部分操作行为,都对应着一个URL后端请求或者前端请求。而这些请求必然会经过nginx进行请求转发,nginx日志会记录每一个请求的信息。
通过对nginx日志的实时监控、采集、入库,我们将用户行为数据标准化入库,从而替代了老式的前端调用埋点接口的方式,减少了开发量,减少了埋点请求数量。
========================下面为具体实现细节=======================
nginx日志JSON格式配置
logformat按照如下格式配置,日志会打印为json格式,便于flume和ets服务做数据解析。
log_format main escape=json '{"ipaddress":"$remote_addr","remote_user":"$remote_user","time_local":"$time_local","request":"$request","request_uri":"$uri","uri_with_args":"$request_uri","request_method":"$request_method","request_id":"$request_id","status":"$status","body_bytes_sent":"$body_bytes_sent","request_body":"$request_body","args":"$args","http_referer":"$http_referer","http_user_agent":"$http_user_agent","http_x_forwarded_for":"$http_x_forwarded_for","request_source":"$http_Request_Source&#