APPKIT打造穩定、靈活、高效的運營配置平臺

美團技術團隊發表於2018-09-21

一、背景

美團App、大眾點評App都是重運營的應用。對於App裡運營資源、基礎配置,需要根據城市、版本、平臺、渠道等不同的維度進行運營管理。如何在版本快速迭代過程中,保持運營資源能夠被高效、穩定和靈活地配置,是我們團隊面臨的重大考驗。在這種背景下,大眾點評移動開發組必須要打造一個穩定、靈活、高效的運營配置平臺。本文主要分享我們在建設高效的運營配置平臺過程中,積累的一些經驗,以及面臨的挑戰和思考。

運營資源

簡單而言,運營資源可以理解為App中經常變動的一些廣告、運營活動等等,譬如下圖中電影首頁頂部的Banner位,就是一個典型的運營資源。對於這類運營資源,它們有如下明顯特徵:

  1. 時效性,只在一定時間範圍內顯示在C端固定位置。
  2. 城市強相關,這類運營資源往往是基於LBS類服務,每個活動、廣告都只會出現在固定的某些城市(或區域)。

APPKIT打造穩定、靈活、高效的運營配置平臺

基礎配置

基礎配置,常見的有入口資源的配置、網路的配置等。相對運營資源來說,其變更的頻繁度相對較低,與時間、城市的關係也沒那麼強。譬如下面大眾點評App-我的頁面裡的入口。這類配置有如下幾個特徵:

  1. 多維度:需要針對不同的版本、平臺、渠道,做不同的配置。
  2. 長期有效:這種型別的配置一般長期存在,不會存在過期問題。

APPKIT打造穩定、靈活、高效的運營配置平臺

二、遇到的問題

在從0到1打造運營配置平臺的過程,我們遇到了很多“坑”。特別是在早期“刀耕火種”的時代,對於入口的配置,往往是通過“hardcode(硬編碼)”的方式寫死在程式碼中。所以必然會遇到很大的問題,這主要體現為以下兩方面:

運營效率低

對於新的運營配置需求,研發同學需要開發對應的配置頁面,然後轉給運營同學進行配置的管理,最後運營人員對資源進行配置上線,其流程如下:

APPKIT打造穩定、靈活、高效的運營配置平臺

對於每個運營配置需求都要經過需求評審、頁面開發、配置管理、上線的流程。同時,對於配置頁面的開發,少則需要1到2天的開發工時,研發成本高。問題總結如下:

  1. 研發成本高,每個需求要開發新的配置管理頁面。
  2. 研發週期長,運營效率低,從需求的提出到運營上線週期長。
  3. 靈活性差,對不同的運營維度(城市、版本、時間等)都需要事先確定好,無法動態調整。

上線流程“粗糙”

在早期,運營配置上線流程需要研發同學參與。產品提出運營配置需求,研發同學通過修改程式碼對配置進行變更,然後通過程式碼上線進行釋出。整體流程如下:

APPKIT打造穩定、靈活、高效的運營配置平臺

這種上線機制存在以下幾個問題:

  1. 配置上線過多依賴於程式碼的釋出。
  2. 整體上線過程無稽核機制,無法對配置資源進行合規稽核。
  3. 配置容易出錯,上線前不能提前預覽上線後的效果,只有“事後”(上線後)才能驗證效果。

三、我們的思考

針對以上問題,我們希望通過設計一個通用的解決方案,去解決上文闡述的各種運營資源管理的問題。我們把這個整體的專案稱之為APPKIT,寓意是App的運營配置工具(Kit)。通過不斷的實踐和總結,我們希望能從三個維度解決上述問題:

資料JSON化

隨著業務的不斷迭代,無論採用怎樣的資料欄位組成,都無法滿足業務變化的欄位(這裡是指像標題、副標題、圖片、跳轉連結等)要求。對底層資料進行JSON化,其對應的資料欄位完全可動態擴充套件,從而滿足業務不斷迭代的需求。JSON化隨之也會帶來運營位欄位管理的問題,我們通過欄位管理的工具來解決這個問題。

運營流程化

設計一套整體的流程管理機制,解決運營的投放、稽核、釋出和回滾的問題。通過流程化的機制,我們實現了“事前”、“事中”、“事後”的三級管理。

首先,在運營配置上線前,通過測試使用者的預覽功能,可以預覽上線後的實時效果。同時,通過穿越功能可檢視將來時段顯示的效果。防止出現上線後連結出錯、視覺效果達不到預期等問題。

其次,在流程階段,引入稽核機制,通過視覺和內容兩方面的稽核,保證投放資料的準確性。

最後,在運營配置上線後,如果發現問題,可以通過快速回滾,最大限度地實現“止損”。

APPKIT打造穩定、靈活、高效的運營配置平臺

介面SDK化

對於運營資料,無論是通過資料庫的落地方案、還是通過分散式快取的方案,都無法徹底解決服務中心化和服務抖動的問題。通過接入的SDK化,可以做到資料的本地快取更新機制,解除對中心化服務的依賴,大大提升服務的穩定性和效能。同時整個APPKIT服務變成可水平擴充套件,在擴充套件過程中也不會影響中心服務的穩定性。

四、APPKIT架構

APPKIT運營配置系統整體框架如下(資料流向如箭頭所示)。從功能角度,大體上分為四層:資料層、服務層、接入層和監控層。

APPKIT打造穩定、靈活、高效的運營配置平臺

4.1 資料層

資料層作為最底層的資料儲存,其儲存了最基本的運營後臺資料、流程資料和線上資料。對持久化的資料,我們採用MySQL進行儲存;對於快取資料,我們採用了Redis的解決方案。這樣資料層形成基本的兩級儲存結構:MySQL保證了資料的永續性,Redis保證了資料獲取的速度。

這裡我們對底層資料劃分為三個不同域:後臺資料,相當於草稿資料,運營人員所有的操作都記錄在這裡;流程資料,運營人員操作完成後,提供釋出流程,預覽及稽核都在流程資料裡進行;線上資料,稽核通過後,資料同步到線上資料,最終C端使用者獲取到的資料都是來源於線上資料。

談到資料層,這裡我們遇到了儲存上的一個小問題。按城市運營的每條資料,都需要儲存具體的城市ID列表,其在資料庫裡的儲存為 “1,2,3,4...... ”這樣字串。而這種資料儲存在業務請求和條件過濾過程中,存在著如下兩個問題:

a. 大資料儲存對記憶體的消耗

美團、大眾點評運營的城市成千上萬,如果每條運營的投放資料都包含大量的城市列表資訊,對機器記憶體勢必產生一定消耗。

b. 過濾效能問題

城市的過濾邏輯大體是這樣:使用者所在城市與從資料庫獲取到的城市列表(“1,2,3,4...... ”)進行匹配,在每次匹配過程中都需要做字串“split”的切割操作。這種操作的特點是流量越大,對機器CPU的消耗越大。

解決方案:基於以上兩點考慮,再結合Java語言提供的BitSet機制。我們從資料庫裡取出城市列表資料後只做一次“split”切割操作,將資料轉化為BitSet型別。這樣在實際過濾過程中只需要通過BitSet的get機制就可以判斷運營投放的城市是否包含了使用者所在的城市。通過BitSet機制,我們既解決了大資料儲存對記憶體的消耗問題,又解決了城市過濾的效能問題。

4.2 服務層

服務層向下對底層資料進行操作;向上為接入層獲取資料提供接入能力。其提供四個服務能力:運營後臺、開放平臺、資料服務、APPKIT-SDK,如下表所列:

APPKIT打造穩定、靈活、高效的運營配置平臺

4.3 接入層

接入層主要為運營人員、業務研發提供接入能力。通過運營流程化為事前、事中、事後提供保障。一個運營資源從製作到最後在C端展示,需要經過運營人員的投放、測試預覽、稽核及釋出的中間流程。這裡對於一些敏感的運營資源,需要通過安全部門的審查。安全審查主要涉及到敏感詞的處理、敏感圖片的檢測等。對運營配置平臺來說,它完全是一個“黑盒模型”。這裡主要涉及到兩種情況:

  1. 資源上線時

APPKIT打造穩定、靈活、高效的運營配置平臺

  1. 資源上線後

APPKIT打造穩定、靈活、高效的運營配置平臺

4.4 監控層

APPKIT-SDK執行在業務機器上,這裡就涉及到多臺機器的資料一致性問題。同時,隨著業務接入運營資料的增多,SDK對機器記憶體勢必有一定消耗。基於服務的穩定性考慮,我們對SDK執行時的投放內容進行監控,其主要監控兩個指標:運營位數及每個運營位的配置總數。這樣做可以帶來以下幾個好處:

  1. 對接入的業務數及機器數進行統計。
  2. 通過SDK的配置總數監控,防止數量超過最大限制。

同時,對於非SDK的其他效能指標,我們採用統一的監控平臺--CAT進行監控,其中包括:APPKIT中心服務的呼叫QPS,機器的效能,網路流量等通用指標。

五、底層模型--靈活性設計

5.1 從一個例子切入

資料模型往往與業務相關。業務越複雜,設計需要越簡單,這樣方能滿足複雜業務的各種變化。因為資料模型太過於抽象,如果直接進行述說會有些乏味,我們可以先從一個具體的業務例項入手。下面是大眾點評App頂部金剛位的截圖,對於這部分資料,如何做到運營可配?

APPKIT打造穩定、靈活、高效的運營配置平臺

首先,我們對運營資料做需求拆解。對於這塊資料,每個 “節點”(對應每個位置:如美食,技術上我們稱之為 “節點”),其基本的運營訴求如下:

  1. 節點內容資訊:標題、圖片、跳轉連結、排序。
  2. 節點的過濾維度資訊:城市、版本、平臺、渠道等。
  3. 節點其他資訊:角標,如外賣節點,其有一個下午茶這樣的角標。值得注意的是,像下午茶這樣的角標,除去文案、文案顏色這些基本資訊之外,我們也可以按城市、平臺、進行過濾(不周的城市對應的文案可能不一樣,如上海為“下午茶”,北京因為嘉年華活動可以改成“嘉年華”)。

上面這個運營場景算是非常經典、複雜的一個運營場景了,如果這個問題解決了,其他問題自然就會迎刃而解。

5.2 技術分析

我們做一下進一步的技術分析:

首先,這裡有節點,每個節點(Node)有其相應的內容(Content),節點與內容是“一對多”的關係。這裡的內容,我們指的是如標題、圖片、跳轉連結等資訊,雖然是“一對多”的關係,但最後在同一個城市、同一個版本下(可選擇)只顯示一條內容。為什麼有這樣的需求?舉一個簡單的業務場景例項,以外賣為例,在新版本10.0的時候做了一個全新的外賣頻道頁面,其連結資訊與老版本的完全不同,這裡我們就需要按版本的不同配置兩條不同的內容資訊。

其次,節點與節點之間有兩層關係,其一為“平級關係”,如美食與外賣的關係,這種關係就是一種簡單的列表關係;其二為樹關係(Tree),如外賣與下午茶之間的關係。這裡我們將角標(下午茶)視為一個節點,因為角標也需要按不同維度進行過濾,因此下午茶成了外賣的子節點。其實這裡有一些特殊的地方,如果角標不需要按城市、版本等維度進行運營,那很簡單它就是一個內容資訊(類似標題)。

最後,我們談一談排序問題,對於這麼多品類,如何排序,他們的優先順序是什麼?我們需要定一個基本的基調,每個節點都有一個基本的排序值(優先順序)。但深入業務分析,對於不同的人(群),每個人關注的點不一樣,需要一個“千人千面”的演算法,來決定每個人所看到的內容是其真正關心的內容。所以,這種應用場景下的排序應該通過機器學習演算法而得到。

5.3 資料建模

針對上面的技術分析,我們提出了一種節點(Node)-內容(Content)-樹(Tree)模型,簡稱為N-C-T模型。如下圖所示:左邊為抽象的資料模型,右邊為以上例項的實現。

APPKIT打造穩定、靈活、高效的運營配置平臺

N-C-T資料模型設計的非常簡單,其中C和T部分都是可選擇的,這樣使得其靈活性比較強,可以應對業務變化的大部分需求。注意,這裡我們只是對業務需求的巨集觀表現形式進行建模,對於具體Node和Content裡的有哪些欄位(標題、副標題、圖片、跳轉連結),這些都是JSON化的儲存格式,可以滿足任意欄位的擴充套件。

5.4 模型的應用與小結

通過以上經典例項,我們可以很容易通過我們的資料模型解決這個問題。我們再回到文章最開頭的背景章節的運營場景,Banner位,如下:

APPKIT打造穩定、靈活、高效的運營配置平臺

這種Banner位,套用我們上的資料模型,它其實是一種只有一個Node節點、多個Content節點的模型。這也是一種典型的應用場景,為此我們總結了兩種應用場景。

APPKIT打造穩定、靈活、高效的運營配置平臺

其實,大部運營場景都可以套用以上兩種經典的運營組合。

六、運營流程化

將運營資源的管理進行流程化,具有以下幾個好處:

  1. 資源上線前可進行嚴格的稽核。
  2. 出問題時可快速回滾。
  3. 記錄使用者的(上線)操作歷史。
  4. 上線前可提前預覽線上效果。

資料域

對於流程化的實現,我們是將資料域切分成三個不同的部分:後臺資料、流程資料和線上資料,如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺

後臺資料:我們可以簡單理解為草稿資料,這裡的資料多使用者可同時進行操作,也不會對線上資料有影響。

流程資料:當使用者後臺資料編輯完成後,對資料提交一個釋出流程,資料進入流程資料區域;這時可對資料進行測試預覽、稽核等操作。

線上資料:這塊資料是C端使用者真正獲取到的資料,當流程資料稽核通過後,資料會自動同步到線上資料域,完成上線操作。

上線流程

整個上線流程如下:

  1. 運營同學對後臺資料進行修改,提交發布流程,同時進行預覽測試。
  2. 稽核同學對提交的釋出流程進行稽核。
  3. 稽核通過,自動釋出到線上(對稽核不通過的流程,資料回退到後臺進行再次編輯)。

為了能平穩上線,我們設計了一個測試預覽功能。當資料處於流程中時,使用者可以通過掃描二維碼加入到測試使用者名稱單,可對處於稽核流程中的資料進行預覽,用美團、大眾點評App檢視上線後實時效果,其實現的資料流如下:

APPKIT打造穩定、靈活、高效的運營配置平臺

七、穩定性的演進

穩定性是一個運營配置平臺最重要的能力,沒有穩定性,其他任何功能都會失去實際意義。運營系統的穩定性經歷了不同的迭代時期,總結起來,可概括為以下三個階段:

7.1 經典方案

這是APPKIT最早期的經典方案,它的實現也非常簡單,如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺

C端使用者通過業務接入層獲取資料,業務接入層通過服務呼叫獲取配置後臺資料(APPKIT服務),配置後臺資料服務讀取快取資料。如果快取資料不存在,則從資料庫中讀取資料,同時將資料庫資料同步到Redis快取中。這是經典的資料獲取模型,但它有以下幾個缺點:

  1. 資料呼叫有網路時延。
  2. Redis快取抖動(網路抖動)會對服務的穩定性產生影響。
  3. 快取的單Key儲存的容量限制。

7.2 快取方案

針對以上經典方案的缺點,我們做了進一步的改進,對配置後臺資料服務做了一層本地記憶體快取,如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺

樣做可以解決資料呼叫的部分網路時延問題,同時Redis快取的抖動也不會影響整體服務的效能。不過,這個方案也有其自身的缺陷。

  1. APPKIT服務成了中心節點,業務方對中心節點強依賴,隨著業務接入越來越多,中心服務的壓力會等比例增加。
  2. 業務接入層與配置後臺資料服務間呼叫的網路時延問題仍然存在。
  3. 單機的Web快取容量有限,隨著業務接入越多,APPKIT伺服器本地快取的資料量越大。

7.3 SDK方案

為徹底解決快取方案的問題,尤其是服務中心化帶來的流量、容量等問題,我們將運營資料的獲取、Web快取的管理整合進SDK。如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺
這樣的話,無論接入再多的業務,也不會對中心服務產生過大的流量壓力和容量壓力。SDK同時也解決了服務間呼叫的網路時延問題。所有同步資料的網路呼叫都是通過後臺執行緒非同步完成,不會影響業務執行緒的正常處理邏輯。

不過,SDK方案也引進了如下的新問題:

  1. 資料時效性和一致性如何保證?
  2. SDK本地快取如何監控?過期資料如何刪除?
  3. SDK版本如何升級?

為了解決資料的時效性和一致性問題,我們引入了監聽更新機制,如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺

運營人員在運營後臺操作完成後,提交上線流程,流程釋出後通過ZooKeeper的變化監控傳送一個變化事件;SDK通過監聽變化事件,拉取變化後的運營資料更新到本地。這裡,為了防止這種監聽機制失效,我們也做了一個兜底策略:每分鐘定期進行一次資料同步。這樣保證資料最遲一分鐘內就能實現同步。對於SDK本地快取,我們設計了監控上報機制,如下圖所示:

APPKIT打造穩定、靈活、高效的運營配置平臺

這裡有兩條線路,其一為SDK在請求資料時,帶上資料的accessTime時間戳,APPKIT服務會根據accessTime時間戳判斷SDK本地資料是否過期。當accessTime時間超過24小時,說明這個運營位在一天內都沒有使用,可以從本地記憶體中進行刪除。其二為SDK定期進行監控上報,上報SDK本地快取的數目,這樣可以對SDK本地快取進行監控和告警。對SDK版本升級問題,現有的解決方案,是通過CI構建時對SDK版本升級進行提示(必要時進行強制),不過大部分運營位使用的都是基礎功能,在很大程度上不需要進行頻繁地升級。

效果對比

快取方案與SDK方案的效果對比如下:

APPKIT打造穩定、靈活、高效的運營配置平臺

注: SDK方案的平均線為0.0是因為統計時舍入引起的,真實值其實非常小。

八、總結與展望

本文通過美團點評移動運營平臺的實踐,詳細介紹了我們在打造穩定、靈活、高效的運營配置平臺過程中遇到的問題和挑戰,同時本文也提供我們的解決思路:通過資料JSON化,運營流程化,介面SDK化分別解決了運營平臺的靈活性、高效性和穩定性。APPKIT幫助產品、運營和研發提升C端的開發和運營效率,加速產品的迭代程式。

目前基於APPKIT的平臺化特性,對App的模組化配置、Picasso的JS的管理、ABTest、個人中心入口管理、魯班(面向C端的Key/Value配置系統)等業務提供了底層的資料儲存和資料獲取的支援,為移動端業務提供了運營配置的基礎保障。

同時,為了進一步提升運營效率,我們基於Picasso的多端(Android、iOS、H5、微信小程式)能力,正在構建移動化的運營能力。這樣保障使用者無論在什麼辦公環境都能進行運營配置的管理。

作者簡介

國寶,美團點評移動運營平臺負責人,Java後端架構師,APPKIT專案發起人,負責APPKIT專案的架構設計。專注於高效能、高穩定、大併發系統的設計與應用。

小龍,目前為APPKIT專案負責人,主要負責APPKIT專案開發、技術對接和實施、開放平臺等。專注於前後端全棧技術開發,喜歡挑戰新的技術和業務問題。

APPKIT打造穩定、靈活、高效的運營配置平臺

相關文章