采集流程
架构图
立方体模型
立方体建模是为了细化采集指标,最大限度得复用数据,减轻埋点工作量,统一埋点口径
埋点事件
事件定义:为了对用户行为进行统计和分析,我们使用一类被称为 “事件” 的消息来记录用户行为。
事件组成
事件维度
事件类型
手动埋点类型
前端埋点
后端埋点
埋点方式
统一口径
定义前端sdk与后端sdk包
方法列表
clickProduct(String userId,Date clickTime,int env,String productId)
payOrder(String userId,Date payTime,int env,String orderId)
login(String userId,Date loginTime,int env,String status)
addShoppingCart(String userId,Date addTime,int env,String productId)
其中最后一个参数可以进行扩展,填充json数据
数据传输方式
可以使用websocket或http,需要对该方式进行池化处理
日志收集服务
可使用netty的IO复用模型实现日志收集,收集的日志存入kafka与数据库
数据从两个点存储
备份
只存储当前时间窗口一年以内的数据,其它数据通过调度定时存入冷备数据库
分析方式
实时分析
kafka数据,消费并进行实时分析,存入数据进入数据库,主要针对增量指标,实时指标
离线分析
通过调度任务,对数据库的数据,进行定时调度,主要针对数据库存量指标,例如:月指标、周指标、年指标
数据存储
分析后数据存储进入到redis集群,按如下格式存入
key :业务线:${userId}:下单量
可视化框架
https://echarts.apache.org/zh/index.html
后端
根据请求实时取redis中的数据,进行组合形成前端需要的数据返回
例如,展示本周的访问量
类与接口设计
顶级事件接口 Event
顶级包装接口 Wrapper
抽象实现类AbstractEvent implements Event
protected static Executor executor,
protected int eventLength
protected Enum state
public abstract boolean add(T t)
事件实现接口XXXXEvent extend AbstractEvent implements Wrapper
private static SocketPool socketPool
构造方法XXXXEvent(){ executor = new ThreadPoolExecutor();socketPool=new SocketPool();} 根据实际情况配置核心线程,最大线程,任务队列,过期策略等参数
public Thread wrapper(T t){},从Socket线程池中获取具体的连接, 然后发送,最后归还到线程池
public boolean add(T t){},先对传入对象做处理,比如加上userId,env等信息,调用wrapper转成Thread对象,放入到executor线程池中等待调度处理
public static void start(){} 启动socketPool与executor
public static void end(){} 销毁socketPool与executor
类图
IO模型
IO多路复用
框架
数据清洗
无用或不符合规格的数据全部舍弃,响应{“code”:-1,“msg”:“useless data or data does not meet specifications”,“data”:null}
时序图
kafka 消费模式
at least onece模式
pull/push
pull(防止消息堆积)
分析
获取数据后对对应数据库存储的指标进行操作,例如基础访问量指标+1,购物车指标+某某商品,redis旁路一份数据
数据类型
实时数据
监控kafka消费处理
历史数据
通过调度凌晨定时处理
数据组装
根据表图需要的信息,从redis获取数据,进行组装,并返回
刷新事件
需求指标
基础指标
数据结构