用最朴素的语言,描述最复杂的方案!!
有没有遇到这样的一个用户场景,哪天在淘宝APP搜索了:50度飞天茅台,然后第二天在头条APP看新闻时,就时不时出现茅台。这就是今天需要讲解的这个场景。
可以说每款APP,或者每个 TO C 系统都存在或少或多的收集数据用户信息和用户行为的操作。收集用户信息和用户用为的操作,一般需要使用到埋点服务。而这个埋点服务,很多第三方服务商都提供了相应的服务,只要根据对应的步骤接口,就可以收集相应的数据。比如,友盟的埋点服务:
https://www.umeng.com/page/z/maidian
第三方的埋点服务,有的是免费的,有的是收费的。如果使用免费的服务呢,万一服务出现问题,可能得不到服务商的及时响应;如果使用收费的服务呢,如果控制不好,又怕把自己这边的大量用户数据提供了给第三方平台,万一第三方搞你的数据,或者不小心泄漏了,找谁说都用。基于以上两种情况考虑,自己搭建一个埋点服务。
0x01:数据库设计
埋点服务的数据库的数据量,根据APP的用户量成指数级别成正比。如果需要的话,可以采用分库分表。详细的表结构设计大致如下:
-
id:主键id
-
platform:平台,枚举类型:iOS苹果,Android安卓,html5,miniapp小程序等
-
user_id:操作用户,登录时为登录用户的id;未登录为NULL
-
user_name:用户姓名
-
sex:用户性别
-
page:操作的界面,枚举类型,需要根据所属模块定义。例如:进入支付界面定义为payment_page_view;最好定义一个规则,例如:模块名 + page + 动作
-
action:操作,insert增加,update更新,delete删除,query查询
-
action_time:操作时间
-
module:所属模块
-
create_date:创建时间
这里只定义了一些通用的字段,其他字段可以根据不同项目,不同的业务场景;自行增加,满足自己的业务需要即可。定义这个表的目标就是可以根据这些收集的数据分析用户的行为习惯;抑或可以根据统计出系统的运营数据,比如用户的活跃量,活跃度等。
0x02:接口设计
埋点数据具有通用性,一般只需一个接口即可。接口一定需要设计为 POST 请求,因为搜集数据,最好设计为批量上送。如果收集一条数据,就请求一次接口,对服务端非常不友好,造成服务器压力。接口的请求参数的DTO ( TrackListDto )大致可以设计为:
-
platform:平台,枚举类型:iOS苹果,Android安卓,html5,miniapp小程序等
-
user_id:操作用户,登录时为登录用户的id;未登录为NULL
-
user_name:用户姓名
-
sex:用户性别
-
sign:签名,验签使用。防止埋点服务被黑客攻击
List
import java.util.List;
public class TrackListDto {
private String platform;
private String user_id;
private String user_name;
private String sex;
private String sign;
private String ts;
private List<TrackInfoDto> list;
//省略 getter setter
}
TrackListDto 还可以定义一些其他的通用属性,需要根据具体业务场景需要定义。
TrackInfoDto定义大致如下:
-
page:操作的界面,枚举类型,需要根据所属模块定义。例如:进入支付界面定义为payment_page_view;最好定义一个规则,例如:模块名 + page + 动作
-
action:操作,insert增加,update更新,delete删除,query查询
-
action_time:操作时间
-
module:所属模块
import java.util.Date;
public class TrackInfoDto {
private String page;
private String action;
private Date action_time;
private String module;
// 省略 getter setter
}
TrackInfoDto还可以定义肯定与用户行为的属性,这里的数据跟数据库一一对应即可,也需要根据具体业务场景需要定义。
0x03:主要实现逻辑
- 客户端
客户端层面,需要根据用户的操作,收集数据整理成 TrackListDto 对象,而该对象的 TrackInfoDto数组,最好到达一定数量,比如10条,20条,在调用一次埋点服务的接口。还有一个关键步骤就是前端与后端要约定一个签名生成的算法,以便生成签名和进行签名验证。
- 服务端
服务端就一个接口,就是接受客户端收集的数据,然后入库。但是要考虑两个问题,第一个就是验证问题,防止客户攻击;第二个就是用户量的并发请求可能造成数据库瓶颈问题。如果用户量大,实时入库,肯定给数据库造成非常大的压力。
验证问题:客户端与服务端约定验签算法即可,算法前后端验签算法要一致。如果需要更安全点的话,就是需要埋点服务进行监控。
用户量的并发请求可能造成数据库瓶颈问题:这个需要引入消息队列 MQ,把先把数据存放到MQ,然后异步入库即可。
虽然设计简单,却是支撑百万级别项目的方案。无论你的方案多牛逼,不能变现的方案都是烂方案!!!