做爲系列文章的第五篇,本文重點探討數據採集層中的微信分享追蹤系統。微信分享,早已成爲移動互聯網運營的主要方向之一,以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