文圖|胡杰 朱明 殷磊
“交管12123”App2016 年上線,截至2023 年6 月底,已累計注冊個人用戶5.1 億個,提供各類服務(wù)達(dá)51.3 億次,社會經(jīng)濟(jì)效益顯著。在為廣大用戶提供穩(wěn)定服務(wù)的同時,“交管12123”App 自身版本迭代、優(yōu)化工作也一直在持續(xù)進(jìn)行,且多為被動式的問題“上報-修改”、建議“反饋-優(yōu)化”,缺乏主動、有效、準(zhǔn)確地分析C 端用戶的真實使用情況的能力,而且對C 端產(chǎn)品質(zhì)量也缺乏量化的分析數(shù)據(jù),為此12123 需要研究客戶端數(shù)據(jù)采集技術(shù)。數(shù)據(jù)采集作為數(shù)字化運(yùn)營中最重要的一環(huán),通過采集、分析客戶端數(shù)據(jù),可以實時跟蹤C(jī) 端產(chǎn)品質(zhì)量,主動發(fā)現(xiàn)問題并預(yù)警,及時進(jìn)行修復(fù)和優(yōu)化,提高App 的穩(wěn)定性和可靠性。本文就基于“交管12123”App 的客戶端數(shù)據(jù)采集的總體思路、關(guān)鍵技術(shù)進(jìn)行研究探討,便于通過分析用戶行為數(shù)據(jù)和反饋信息,增強(qiáng)對用戶需求和行為的了解,從而更好地進(jìn)行產(chǎn)品設(shè)計和優(yōu)化,提高用戶體驗感和滿意度。
以App 前端視角觀察整個系統(tǒng),通過埋點方式搜集 App 用戶終端的行為信息,通過海量數(shù)據(jù)的統(tǒng)計分析,及時發(fā)現(xiàn)問題及優(yōu)化方向。一是在不影響現(xiàn)有業(yè)務(wù)邏輯的情況下,以旁路監(jiān)控數(shù)據(jù)埋點的方式,采集客戶端數(shù)據(jù),數(shù)據(jù)采集盡量與業(yè)務(wù)邏輯解耦。二是由于終端使用場景復(fù)雜且不可控,所以需要使用多種策略盡量提高數(shù)據(jù)的準(zhǔn)確性、完整性和及時性。三是采集的數(shù)據(jù)要盡可能有效、符合數(shù)據(jù)分析的需求,同時為了降低傳輸及存儲的資源消耗,單條數(shù)據(jù)內(nèi)容要盡可能精簡。如圖1 所示,由“交管12123”手機(jī)終端記錄數(shù)據(jù),然后通過訪問部平臺APM 服務(wù)提供的接口上傳日志數(shù)據(jù),最終部平臺通過日志采集分析組件Flume 將采集的日志數(shù)據(jù)聚合、分析后存儲至大數(shù)據(jù)平臺HBase、MPPDB等數(shù)據(jù)庫中。
圖1 總體構(gòu)架
現(xiàn)在業(yè)界主流的埋點方式包括代碼埋點、全埋點、可視化埋點三種。三種埋點方式各有優(yōu)缺點,本文采用的是混合方式,即全埋點為主、部分代碼埋點為輔。針對“交管12123”App 框架層面的埋點,通常采用全埋點的方式,如網(wǎng)絡(luò)層http 監(jiān)控埋點。如圖2 所示,針對http 網(wǎng)絡(luò)層的數(shù)據(jù)采集,本文采用AOP(面向切面編程)的方式,通過記錄http 請求各個階段的切面時間,以此計算分析每個http 請求各階段耗時情況、狀態(tài)結(jié)果(該部分計算由手機(jī)終端完成,并不占用服務(wù)端資源),最終生成標(biāo)準(zhǔn)格式的數(shù)據(jù),可用于后端直接分析處理。而針對上層的業(yè)務(wù)數(shù)據(jù)埋點需求,本文采用代碼埋點的方式記錄數(shù)據(jù),這種方式工作量較大,但自定義程度高,可以更精準(zhǔn)控制埋點的位置、更方便更靈活地自定義事件和屬性,滿足更精細(xì)化的業(yè)務(wù)分析需求。
圖2 網(wǎng)絡(luò)層http切面
在數(shù)據(jù)分析中,一般都是采用“事件模型”來描述用戶在產(chǎn)品上的各種行為。它通過who、when、where、how、what 記錄了誰在某個時間點、某個地方、用某種方式、做了某一件事情(某個行為)。who、when、where、how、what 即是事件模型的五個要素。因此,本文數(shù)據(jù)格式的定義也是圍繞這五個方面來展開,每一條數(shù)據(jù)都代表了一個事件,都需要包含這五個最基本的要素。其中,Who- 事件參與者(用戶id,設(shè)備指紋);When- 事件發(fā)生的時間(時間戳);Where- 事件發(fā)生的地點(頁面id,功能id);How- 事件發(fā)生時的狀態(tài)(用戶使用的設(shè)備信息、應(yīng)用程序版本號、操作系統(tǒng)版本號、渠道信息等);What- 事件的具體內(nèi)容(事件id,事件名稱)。
如圖3、圖4 所示,本文記錄的事件都包含info和data 兩部分,其中,info 是數(shù)據(jù)的基礎(chǔ)部分,里面包含事件模型的五個要素;data 是數(shù)據(jù)的內(nèi)容部分,里面攜帶了具體事件的詳細(xì)信息,根據(jù)不同的埋點數(shù)據(jù)類型,data 部分可以自定義實現(xiàn)。同時為了降低數(shù)據(jù)冗余提高傳輸效率,info 和data 是一對多關(guān)系,即多個data 可以共用一個info。
圖3 info部分
圖4 data部分
因為手機(jī)終端的使用場景比較復(fù)雜且不可控制,所以為了保證單個設(shè)備采集數(shù)據(jù)的準(zhǔn)確性、完整性和及時性,需要針對不同的場景,使用多種數(shù)據(jù)上傳同步策略。一是啟動同步,分為冷啟動、熱啟動兩種情況。冷啟動的情況下,先檢查本地磁盤上是否有緩存未同步的數(shù)據(jù),如果有就立即上傳;熱啟動也是同樣的同步策略,但是檢查的是內(nèi)存中未同步的數(shù)據(jù)。二是定時同步,即手機(jī)終端每隔一定的時間間隔同步一次(比如每隔30 秒)。三是定量同步,即客戶端本地已緩存的數(shù)據(jù)超過一定條數(shù)時同步數(shù)據(jù)(比如100 條)。四是即時同步,適用于對數(shù)據(jù)及時性要求比較高的數(shù)據(jù)類型,也用于防止特殊場景造成的數(shù)據(jù)丟失等,比如應(yīng)用程序進(jìn)入后臺時嘗試同步本地已緩存的所有數(shù)據(jù),最大限度地保證數(shù)據(jù)的完整性。除了以上四種策略外,還有其他保障機(jī)制保證數(shù)據(jù)的完整性,比如失敗重傳,即對于偶發(fā)單次同步上傳的數(shù)據(jù)失敗情況,需要增加重傳機(jī)制,把數(shù)據(jù)重新加入到待傳隊列之中。同時,為了節(jié)約服務(wù)端資源,避免同步大量無效數(shù)據(jù)到服務(wù)端,每個終端默認(rèn)不傳數(shù)據(jù),由服務(wù)端下發(fā)指令控制終端設(shè)備的數(shù)據(jù)采集是否開啟,同時服務(wù)端也可以控制采集數(shù)據(jù)閾值,對于某些類型的數(shù)據(jù),觸發(fā)閾值才會被記錄。
在事件模型里,時間的準(zhǔn)確性尤為重要,因為后續(xù)的數(shù)據(jù)分析和問題回溯都依賴于時間的準(zhǔn)確性。最簡單的方案就是把用戶手機(jī)設(shè)備的時間戳作為事件發(fā)生時間,但有些用戶手機(jī)設(shè)備是不準(zhǔn)確的,從而導(dǎo)致系統(tǒng)采集到的時間不準(zhǔn)確。另一種方案是使用服務(wù)端的時間戳作為事件發(fā)生的時間,但這個方案也不準(zhǔn)確,因為事件信息記錄后,并不會立即同步給服務(wù)端(比如每隔30 秒定時同步),從而導(dǎo)致無法及時獲取服務(wù)端的時間戳。經(jīng)過一段時間的探索和測試,本文最終采用的是“時間修正”策略。如圖5 所示,用戶在手機(jī)時間戳T1時觸發(fā)了一個事件,本地緩存記錄該事件數(shù)據(jù)。在用戶手機(jī)時間戳T2 時開始同步數(shù)據(jù),然后服務(wù)端獲取到數(shù)據(jù)時間戳T2。如果T2 與當(dāng)前服務(wù)端的時間戳T3 的誤差在一定的可接受范圍之內(nèi)(比如30 秒以內(nèi),http 網(wǎng)絡(luò)請求也需要時間),就可以認(rèn)為當(dāng)前用戶手機(jī)的時間戳是準(zhǔn)確的,同時也認(rèn)為事件發(fā)生的時間戳T1 也是準(zhǔn)確的,服務(wù)端在接收到事件信息時直接記錄事件時間為T1,無需額外處理。但如果T2 與T3相差比較大(比如圖4 中的T2 為13:00:00,T3 為14:00:00),則認(rèn)定當(dāng)前用戶手機(jī)的時間戳T2 是不準(zhǔn)確的,即比服務(wù)端的時間戳晚了一個小時,從而就可以推斷事件發(fā)生時的時間戳T1 也比服務(wù)端晚了一個小時,即12:00:00 變?yōu)?3:00:00。因此,服務(wù)端在接收到事件信息時會將T1 修正為13:00:00,從而就達(dá)到了“時間修正”的效果。
圖5 時間糾正示意
針對事件分析來說,首先需要標(biāo)識事件,即事件模型里的Who,選取合適的標(biāo)識,對于提高數(shù)據(jù)分析的準(zhǔn)確性有很大的影響,本文是使用設(shè)備指紋作為事件標(biāo)識。設(shè)備指紋在事件模型中的作用是標(biāo)識設(shè)備的唯一性,通過采集設(shè)備各項信息,如硬件、網(wǎng)絡(luò)、系統(tǒng)等,并將這些信息組合起來,形成一個唯一的設(shè)備標(biāo)識,并通過多種關(guān)聯(lián)和相似查找算法來保障這個標(biāo)識的穩(wěn)定不變。
設(shè)備指紋的研究主要包括兩個部分:設(shè)備指紋如何生成以及如何保持穩(wěn)定。一是關(guān)于設(shè)備指紋的生成,受隱私政策法規(guī)的影響,目前業(yè)內(nèi)沒有一種完美的方案,所以只能在現(xiàn)有的條件和限制之下,尋找一種相對比較完美的方案。本文采用的是漸進(jìn)式獲取方式IDFA(廣告標(biāo)識符)→IDFV(應(yīng)用開發(fā)商標(biāo)識符)→UUID(通用唯一標(biāo)識符),獲取到系統(tǒng)提供的標(biāo)識后,再附加額外的設(shè)備信息(網(wǎng)絡(luò)、系統(tǒng)等),通過自研算法生成一個長度、格式固定的標(biāo)識字符串,以此作為設(shè)備指紋。二是對于設(shè)備指紋如何保持穩(wěn)定,不管是使用IDFA 還是IDFV,用戶限制廣告追蹤或App 卸載重裝,都有可能導(dǎo)致發(fā)生變化,為了保證用戶卸載App 后設(shè)備指紋不變,本文采用的方式是將其保存在Keychain(系統(tǒng)密碼管理系統(tǒng))中,如果應(yīng)用程序被卸載了,下次安裝啟動時優(yōu)先會從Keychain 中尋找而不是重新生成,以此保證設(shè)備指紋的穩(wěn)定性。
崩潰屬于一種特殊的事件且數(shù)據(jù)的優(yōu)先級比較高,所以數(shù)據(jù)的采集、存儲、同步也比較特殊,目前比較成熟的做法是在崩潰發(fā)生時,將崩潰的錯誤棧信息保存到磁盤,下次啟動時同步到服務(wù)端。用這種做法搜集到的崩潰信息,大部分可以順利定位到問題代碼并即時修復(fù),但本文面對億級體量的手機(jī)設(shè)備群體,線上的崩潰問題五花八門,始終有小比例的疑難崩潰無法解決。經(jīng)過長期探索,本文目前采用了“現(xiàn)場恢復(fù)”的策略,在檢測到崩潰發(fā)生的同時,記錄崩潰發(fā)生前一段時間的事件信息,同步上傳到服務(wù)端,服務(wù)端根據(jù)時間順序還原用戶崩潰前的操作情況,為分析具體崩潰原因提供了額外的數(shù)據(jù)支撐,目前這個策略效果顯著。
綜上所述,本文以App 前端視角觀察整個系統(tǒng),通過埋點方式搜集前端數(shù)據(jù),在手機(jī)終端使用場景復(fù)雜且不可控的情況下,盡可能提高數(shù)據(jù)的準(zhǔn)確性、完整性和及時性,同時為了降低傳輸及存儲的資源消耗,在不影響現(xiàn)有業(yè)務(wù)邏輯的情況下,以旁路監(jiān)控方式采集數(shù)據(jù),從而在更好地了解產(chǎn)品內(nèi)在性能和用戶使用情況同時,為整個系統(tǒng)優(yōu)化提供了數(shù)據(jù)支撐,進(jìn)一步提升了“交管12123”App 的用戶體驗,為提高12123 平臺服務(wù)水平和服務(wù)質(zhì)量創(chuàng)造有利條件。