做为系列文章的第五篇,本文重点探讨数据采集层中的微信分享追踪系统。微信分享,早已成为移动互联网运营的主要方向之一,以Web H5页面(下面称之为微信海报)为载体,利用微信庞大的好友关系进行传播,实现宣传、拉新等营销目的。如下图为例,假设有一个海报被分享到了微信中,用户A与B首先看到了这个海报,浏览后又分享给了本身的好友,用户C看到了A分享的海报,浏览后继续分享给了本身的好友。这便造成了一个简单的传播链,其中蕴含了两种数据:css
这样的数据的意义在于:第一,统计分析各个渠道的海报的传播效果;第二,对传播贡献较大的用户发放微信红包奖励,提升用户的分享积极性。微信分享追踪系统,即是完成对这两种数据的采集和存储。在过去的一年里,受到公司业务和运营推广方向的影响,这部分数据驱动了近一半的推广业务。
熟悉微信开发的朋友应该知道,第一,每一个微信用户在某个公众号下都拥有一个惟一的open_id,打开微信海报时,能够经过OAuth2静默受权在用户无感知的状况下拿到其open_id;第二,经过微信JS-SDK,咱们能够捕捉到用户对海报页面的分享事件;第三,拿到用户在公众号下的open_id后,即可以对该用户发放微信红包了。基于这三点,咱们即可以实现相关的数据追踪和分享奖励了,本文主要是总结咱们在微信分享追踪上的方案演进。前端
首先要说一点的是,其实微信分享追踪系统自己并不复杂,可是与复杂的产品业务结合到一块儿,就变得愈来愈复杂了。如何作到将数据逻辑与产品业务逻辑剥离开,以不变应万变,就是这里要说的方案演进了。mysql
早期的微信分享追踪系统,笔者曾经在浅谈微信公众号营销背后的技术一文中介绍过,其时序图以下所示。基本流程是:第一,用户打开海报时,经过OAuth2受权,将open_id加入到页面连接中;第二,前端上报浏览事件,须要带上open_id和传播链信息;第三,用户分享时,须要在分享出去的连接中加上传播链信息,所谓传播链信息,就是每一个分享过的用户的open_id组合,好比“open_id_1;open_id_2”;第四,上报用户的分享事件,须要带上open_id和传播链信息。后端收到上报数据后,根据不一样的功能需求,将数据保存到不一样的数据表中,用于后期消费。随着业务的发展,这个系统暴露出一些问题:sql
因而,咱们思考,有没有可能在后端直接构建完整的传播信息,后期使用时直接根据条件就能够查询出所需的数据,前端上报时也不用携带传播链信息,咱们想到了图形数据库存储技术。
图形数据库是一种非关系型数据库,它应用图形理论存储实体之间的关系信息。在文章开头的那张传播图中,用户的行为数据其实能够归结为用户与海报之间的关系数据,这样,这个系统其实就包含两种实体:用户、海报,三种关系:用户打开海报、用户分享海报、用户之间的传播。在诸多图形数据库中,咱们决定选择比较成熟、文档相对丰富的neo4j来作DEMO。采用neo4j的查询语法,很简单的就能够查询出所需数据,简单示例一下。数据库
# 查询1度分享者
MATCH (u:User) - [:FORWARD] -> (p:Poster) RETURN u # 查询浏览状况 MATCH (u:User) - [:OPEN] -> (p:Poster) RETURN u
下图呈现基于neo4j存储的新系统时序图,在OAuth2受权的重定向过程当中,创建User和Poster节点信息,以及两者之间的OPEN关系信息,而且对页面URL计算hash值(去除无用参数信息),而后将用户open_id和URL的hash值加到页面URL中返回给前端。用户分享时,把该用户的open_id做为parent字段值,加到分享连接中,新用户打开该连接时,会根据该值来创建User与User节点之间的SPREAD关系信息。在用户分享的事件中,作一次数据上报,携带open_id和页面URL的hash值便可,后端拿到信息后,即可以创建User与Poster之间的FORWARD关系信息。如此,即可以创建完整的微信分享追踪数据了。后端
然而,一切并不是预期的那么完美,在DEMO过程当中,咱们发现有两点问题不能很好的知足咱们的需求:微信
# 查询2度分享者
MATCH (u1:User) - [:SPREAD] -> (u2:User) - [:FORWARD] -> (p:Poster) RETURN u2, p
虽然这些问题能够想办法绕过去,好比根据时间创建不一样的实体节点等等,可是这样会把数据存储作复杂化,通过权衡,咱们暂时搁置了这个方案。微信开发
在创业公司作数据分析(三)用户行为数据采集系统一文中,曾经提到早期的数据采集服务是分散在各个业务功能中的,后来咱们从新构建了统一的用户行为数据采集系统。在完成这个系统后,咱们开始考虑将上述的微信分享追踪系统并入其中,主要工做有:spa
经过这样的改进,咱们暂时解决了前端上报混乱和后端业务逻辑膨胀的问题,将数据上报和业务需求隔离开。数据方面,实时数据流在Kafka中,历史数据也在Elasticsearch中有存储;业务需求方面,来了一个新的需求后,咱们只需添加一个新的worker来实现消费逻辑,活动结束后停掉worker。.net