如何在一周内上线50个用户增长策略
在閑魚用戶增長業(yè)務上的實驗
我們最先落地的業(yè)務是在用戶增長上,閑魚的用戶增長業(yè)務有如下描述:
- 閑魚的賣家都是普通小賣家,而非專業(yè)的B類商家。因此無法統(tǒng)一組織起來參加營銷活動帶來買家活躍。
- 我們目前DAU已經(jīng)突破到2000W,如何承接好這么大體量的用戶,對運營同學是個很大的考驗。
在年初時,我們在用戶增長下做了多個實驗,其中兩個實驗如下:
之所以會做以上實驗,主要還是希望用戶能在APP上多停留一會。當用戶瀏覽時間越長,就越有可能發(fā)現(xiàn)閑魚上還有很多有趣的內(nèi)容,無論是商品寶貝還是魚塘內(nèi)的帖子。從而達到吸引用戶下一次還能再回來的目的,最終帶來用戶增長。我們做的實驗上線后大部分都取得了不錯的業(yè)務效果,但是在過程中也暴露了兩個問題:
- 研發(fā)周期長。一開始,我們先用最快的實現(xiàn)方案來做,主要是為了快速驗證規(guī)則策略的有效性,并沒有做大而全的設計,每個需求都是case by case地寫代碼來實現(xiàn)。那么從開始開發(fā)真正能到上線,很可能就是三周,主要因為客戶端發(fā)版是有窗口的。
- 運營效率慢。因為上線慢,導致獲取業(yè)務數(shù)據(jù)后再分析效果就很晚了,然后還要根據(jù)數(shù)據(jù)再去做調(diào)整那就更晚了。這樣算下來,一年也上不了幾個規(guī)則策略。
工程化解法——基于事件流的規(guī)則引擎
針對上述問題,我們先做了一層業(yè)務抽象。運營先通過對用戶的各種行為進行一個分析和歸類,得出一個共同的具體的規(guī)則,再將這個規(guī)則實時地作用到用戶身上進行干預。
針對這層業(yè)務抽象,我們再做了工程化,目的就是為了提升研發(fā)效率和運營效率。這樣就有了第一個方案——基于事件流的規(guī)則引擎,我們認為用戶的行為是一串順序的行為事件流,使用一段簡單的事件描述DSL,再結合輸入和輸出的定義,就可以完整地定義一個規(guī)則。
以上述用戶增長的第二個實驗為例,如下圖所示的DSL即可簡單表達出來:
規(guī)則引擎的局限性
該規(guī)則引擎可以很好地解決之前用戶增長業(yè)務下的幾個策略,隨后我們進行了內(nèi)部推廣,準備在閑魚C2C安全業(yè)務下也落地。在C2C安全業(yè)務上有如下描述:
在C2C安全業(yè)務上,也有一個看似是一個針對一系列行為作出的規(guī)則抽象,如下圖所示:
但是將上述規(guī)則套上規(guī)則引擎后,就會發(fā)現(xiàn)無法將安全的規(guī)則套上規(guī)則引擎。假設我們的詳細規(guī)則是1分鐘內(nèi)被拉黑2次,就對該用戶打上高危標記。那么我們想一想,當來了第一個拉黑事件后,匹配上了。然后緊接著來了第二個拉黑事件,也匹配上了。此時按照規(guī)則引擎的視角,條件已經(jīng)滿足了,可以進行下一步操作了。但是再仔細看一看規(guī)則,我們的規(guī)則是要被不同的用戶拉黑,因為有可能是同一個用戶操作了多次拉黑(同時多開設備)。而規(guī)則引擎上只知道匹配到了2次拉黑事件,對規(guī)則引擎來說已經(jīng)滿足了。卻無法知道是否是不同人操作的。起根本原因是因為在規(guī)則引擎里,事件都是無狀態(tài)的,無法回溯去做聚合計算。
新的解決方案
針對規(guī)則引擎的局限性,重新分析和梳理了我們的實際業(yè)務場景。并結合了業(yè)界知名的通用的解決方案后,設計出了新的方案,定義了新的DSL。可以看到,我們的語法是類SQL的,主要有以下幾個考慮:
- SQL已經(jīng)是語義完備的編程語言,不用再去做額外的語法設計。
- SQL是一門很簡單的語言,不需要花太多時間就可以掌握。
- 我們閑魚的運營同學會寫SQL,這樣會讓上線效率更快。
新的DSL方案與之前的規(guī)則引擎相比主要有以下幾個增強:
- 增加了條件表達式。可以支持更豐富更復雜的事件描述,也就能支撐更多的業(yè)務場景。
- 增加了時間表達式。通過WITHIN關鍵字,定義了一個時間窗口。通過HAVING之后跟的DISTINCT等關鍵字,就可以針對時間窗口內(nèi)的事件進行聚合計算。使用新的方案,就可以很好地解決上述C2C業(yè)務上的規(guī)則描述問題。
- 擴展性強。遵循了業(yè)界標準,與具體業(yè)務的輸入和輸出無關,便于推廣。
針對之前的C2C業(yè)務上的規(guī)則描述問題,使用新方案的例子如下:
整體分層架構
基于這套用EPL(Event Programming Language)寫出的DSL,為了做好工程化,我們做了如下的整體分層架構。為了快速實現(xiàn)最小閉環(huán)驗證效果,我們選擇先基于Blink(Blink是阿里對Flink的內(nèi)部優(yōu)化和升級)做云上的解析和計算引擎。
在這個分層架構里,至上而下分別是:
- 業(yè)務應用。在這里是我們整個系統(tǒng)的業(yè)務方,已經(jīng)在多個業(yè)務場景下做了落地。
- 任務投放。這里是對業(yè)務應用層提供DSL聲明和投放的能力,能可以做簡單的圈人,以及與用戶觸達模塊的關聯(lián)。
- 用戶觸達。這個模塊用于接收來EPL引擎計算的結果,根據(jù)關聯(lián)的Action來實施動作。同時這個模塊也可以獨立對業(yè)務應用提供服務,即各個業(yè)務方可以擁有自己的邏輯,通過用戶觸達模塊來觸達用戶。
- EPL引擎。目前已經(jīng)實現(xiàn)了云上的解析和結算。用于接收來自任務投放里聲明的DSL,再去解析和運行在Blink上。
- 事件采集。負責通過服務端日志和行為打點里采集行為事件,并歸一化地輸出給EPL引擎。
事件采集
通過切面的方式攔截所有的網(wǎng)絡請求和行為打點,再記錄到服務端日志流里。同時通過一個事實任務對事件流進行清洗,按前面定義的格式清洗出我們想要的事件。再將清洗后的日志輸出到另一個日志流里,供EPL引擎來讀取。
EPL實現(xiàn)
由于我們采取了類SQL語法,而Calcite是業(yè)界通用的解析SQL的工具,因此我們采用Calcite并通過自定義其中的parser來解析。如果是單一事件的DSL,則會解析成Flink SQL。如果是多事件的DSL,則會解析后通過直接調(diào)用Blink的API接口的方式來實現(xiàn)。
用戶觸達
當EPL引擎計算出結果之后,會輸出給用戶觸達模塊。首先會進行一個Action路由,最終決策出需要由具體哪一個Action來響應,最后通過與客戶端之間的長連接將Action下發(fā)到端上。端上收到具體的Action后,會先判斷當前用戶的行為是否允許展示該Action。如果可以的話,就直接執(zhí)行Action的具體內(nèi)容,曝光給用戶。用戶看到這次響應后會有相應的行為,那么這部分的行為會影響到Action路由,對這次的路由的做出一個反饋。
案例
新方案上線后,我們就在越來越多的業(yè)務場景里進行了落地。這里列舉2個例子:
在上述魚塘的例子里,可以看出來,我們這套方案已經(jīng)有了一點算法推薦的影子了。在上述租房的例子里,由于規(guī)則過于復雜,用DSL表達起來很麻煩,所以就做成只采集4次瀏覽不同租房寶貝的規(guī)則,即觸發(fā)后,就將這里的數(shù)據(jù)都給到租房的具體開發(fā)的業(yè)務方,這也是我們在落地過程中摸到的邊界。
結論
使用這一套完整方案,研發(fā)效率上有了很大的提升。原先通過寫代碼case by case的方式一般要4個工作日完成整個研發(fā)流程,極端情況下需要跟客戶端版本則需要2-3周的時間。現(xiàn)在通過寫SQL的方式一般要0.5個工作日即可上線。此外,這套方案還有如下幾個優(yōu)勢:
- 高性能。整條鏈路計算完畢平均耗時5秒。
- 高可靠。依托于Blink的高可靠性,承載了雙十一上億的流量。
通過在多個業(yè)務的落地實踐,我們也摸索出來這套方案的適用邊界:
- 對實時性要求高
- 強運營主導規(guī)則
- 能夠用SQL表達
未來規(guī)劃
當前整套方案還有如下幾個問題:
- 整條鏈路計算完畢平均需要5秒左右。如果放到對實時性要求更高的游戲任務場景下時,這就無法滿足了。假設,今天有個任務是瀏覽10個寶貝詳情。當用戶瀏覽到第10個寶貝時,還要再等5秒才給予響應,用戶是無法接受的。因此需要對整體性能有進一步提升,要在毫秒級內(nèi)給出響應。
- 閑魚的業(yè)務已經(jīng)連年保持了高增長,未來可能會面對比當下翻三番的用戶流量,如果所有計算依然全部放在云上,則對云上的算力消耗是個極大的挑戰(zhàn)。
- 目前我們的設計上,是沒有算法接入的,只有簡單的圈人。而為了讓規(guī)則的投放更加精準,進而提升規(guī)則對用戶的有效性,是需要與算法結合的。
因此綜上,我們未來的規(guī)劃將會聚焦于端側實時計算能力的挖掘和算法能力的結合上。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉載。
總結
以上是生活随笔為你收集整理的如何在一周内上线50个用户增长策略的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 据说这是双11前互联网人的一天~
- 下一篇: 开源性能可视化工具——FlameScop