3、数据采集与埋点:客户端埋点技术、服务端拦截器、日志采集与Agent部署
好,咱们进入第三个章节。数据采集与埋点。
说实话,这是整个风险链路追踪里最「脏」最「累」的活。你算法再牛,模型再准,数据采不上来,一切都是白搭。我见过太多项目,架构图画得漂漂亮亮,一到埋点环节就崩了——要么漏数据,要么性能扛不住。
这一章,咱们就把埋点这件事掰开揉碎。客户端怎么埋?服务端怎么拦?日志怎么采?Agent怎么部署?一个一个来。
3.1 客户端埋点技术:从用户行为到风险信号
客户端埋点,说白了就是在用户设备上「装个探头」。用户点了什么、滑了什么、输入了什么,这些行为数据是风险判断的第一手素材。
3.1.1 埋点的三种姿势
我个人习惯把客户端埋点分成三类,你想想看,其实就这三种:
| 类型 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 代码埋点 | 在业务代码里手动插入采集逻辑 | 精准、可控 | 侵入性强,维护成本高 |
| 可视化埋点 | 通过配置平台圈定页面元素,自动采集 | 无需发版,运营可配 | 灵活性差,复杂场景搞不定 |
| 无埋点(全埋点) | 自动采集所有用户交互事件 | 覆盖全面,不漏数据 | 数据量大,噪音多 |
我在项目中遇到过最典型的场景:运营同学说「我要看用户点击这个按钮的转化率」,代码埋点要等排期,可视化埋点圈不准,最后用了全埋点——数据是有了,但每天几亿条事件,光清洗就搞了三天。嗯,这里要注意:全埋点不是银弹,它适合做「数据储备」,不适合做「精准分析」。
3.1.2 关键埋点事件清单
做风险链路追踪,哪些事件必须埋?我列个清单,你照着抄就行:
- 页面生命周期:进入、离开、停留时长、页面切换路径
- 交互行为:点击、长按、滑动、输入框聚焦/失焦
- 敏感操作:登录、注册、支付、修改密码、绑定手机
- 设备指纹:IP、UA、屏幕分辨率、时区、语言、电池状态
- 异常事件:JS报错、网络请求失败、白屏、卡顿
pay_checkout_click。别用中文,别用拼音,不然后面数据分析的时候你会想骂人。
3.1.3 客户端SDK设计要点
客户端埋点通常封装成SDK。我设计SDK时,有几个原则:
- 异步非阻塞:采集逻辑不能卡主线程。用队列+定时器批量上报。
- 本地缓存:网络不好时,数据先存本地。我建议用SQLite或LevelDB,别用SharedPreferences,数据量大时会崩。
- 去重与采样:同一个事件在短时间内重复触发,要合并。高频事件(比如滑动)要采样,别全报。
- 隐私合规:敏感信息(身份证、手机号)必须脱敏。嗯,这个现在法律管得很严,别踩红线。
// 伪代码:客户端埋点SDK核心逻辑
class TrackerSDK {
constructor() {
this.queue = [];
this.timer = setInterval(() => this.flush(), 5000);
}
track(eventName, params) {
const event = {
name: eventName,
params: this.sanitize(params), // 脱敏
timestamp: Date.now(),
deviceId: this.getDeviceId()
};
this.queue.push(event);
if (this.queue.length > 50) this.flush(); // 批量上报
}
flush() {
if (this.queue.length === 0) return;
// 发送到服务端
navigator.sendBeacon('/track', JSON.stringify(this.queue));
this.queue = [];
}
sanitize(params) {
// 脱敏逻辑:手机号中间4位变*
if (params.phone) params.phone = params.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
return params;
}
}
3.2 服务端拦截器:在请求入口处「截胡」
客户端埋点搞定了,但还不够。为什么?因为客户端数据可能被篡改。用户用个抓包工具,或者直接改代码,就能伪造事件。所以,服务端必须有自己的采集手段。
服务端拦截器,就是在请求进入业务逻辑之前,先「截」一道。把请求的元数据、参数、上下文都记录下来。
3.2.1 拦截器架构
我一般用过滤器(Filter)或拦截器(Interceptor)来实现。以Java为例:
// Spring Boot 拦截器示例
@Component
public class RiskTraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 采集请求元数据
RiskContext context = new RiskContext();
context.setIp(getClientIp(request));
context.setUserAgent(request.getHeader("User-Agent"));
context.setRequestUri(request.getRequestURI());
context.setRequestParams(request.getParameterMap());
context.setTimestamp(System.currentTimeMillis());
// 存入ThreadLocal,供后续业务使用
RiskContextHolder.set(context);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 请求结束,清理上下文
RiskContextHolder.clear();
}
private String getClientIp(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.isEmpty()) ip = request.getRemoteAddr();
return ip;
}
}
3.2.2 采集哪些数据?
服务端拦截器采集的数据,我分成三类:
- 网络层:IP、端口、协议、请求方法、Content-Type
- 身份层:用户ID、SessionID、Token、Cookie
- 业务层:请求参数、响应状态码、处理耗时、异常堆栈
你想想看,这些数据组合起来,能干什么?比如:同一个IP在1秒内发了100个不同用户的登录请求——这明显是撞库攻击。没有服务端拦截器,你根本抓不到这个特征。
3.3 日志采集与Agent部署:让数据「流」起来
客户端和服务端的数据都采了,但它们是分散的。怎么汇聚到一起?靠日志采集和Agent。
3.3.1 日志采集的经典架构
我画个图,你一看就明白:
这个架构,说白了就是三个环节:采集 -> 传输 -> 消费。每个环节都有讲究。
3.3.2 Agent部署的注意事项
Agent部署,我踩过的坑比吃过的盐还多。说几个关键点:
- 资源占用:Agent不能吃太多CPU和内存。我建议限制在单核5%以内,内存不超过200MB。否则业务方会找你拼命。
- 日志轮转:应用日志必须配置轮转(log rotation),不然Agent会把磁盘读爆。我曾经遇到过日志文件100GB,Agent直接OOM。
- 断点续传:Agent挂了重启,要能接着上次的位置读,不能重复也不能遗漏。Filebeat的registry文件就是干这个的。
- 安全认证:Agent到消息队列之间要加密。别裸传,万一被人截了,用户数据就泄露了。
3.3.3 日志格式标准化
我强烈建议统一日志格式。不然每个团队写日志的格式都不一样,解析起来想死。我推荐用JSON格式:
{
"timestamp": "2025-01-15T10:30:00.123Z",
"level": "INFO",
"traceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"spanId": "span-001",
"service": "user-service",
"method": "com.risk.user.service.login",
"params": {"userId": "u_10086", "ip": "192.168.1.1"},
"cost": 45,
"status": 200,
"message": "用户登录成功"
}
你看,traceId和spanId都有了,这就是链路追踪的基础。后面讲到「分布式追踪」的时候,你会更深刻地理解这两个字段的价值。
3.4 本章小结
数据采集与埋点,是整个风险链路追踪的「地基」。地基不稳,上面盖什么都是危楼。
客户端埋点要轻量、异步、合规;服务端拦截器要快、准、不阻塞;日志采集要标准化、Agent要轻量化。这三板斧砍下去,数据就能稳稳地流到你的风控引擎里。
嗯,下一章咱们聊聊数据到了之后怎么存、怎么查。不过那是后话了,先把今天的代码写出来跑通再说。
公众号:蓝海资料掘金营,微信deep3321