廣告是網際網路變現的重要手段之一。
以馬蜂窩旅遊 App 為例,當用戶開啟我們的應用時,有可能會在首屏或是資訊流、商品列表中看到推送的廣告。如果剛好對廣告內容感興趣,使用者就可能會點選廣告了解更多資訊,進而完成這條廣告希望完成的後續操作,如下載廣告推薦的 App 等。
廣告監測平臺的任務就是持續、準確地收集使用者在瀏覽和點選廣告這些事件中攜帶的資訊,包括來源、時間、裝置、位置資訊等,並進行處理和分析,來為廣告主提供付費結算以及評估廣告投放效果的依據。
因此,一個可靠、準確的監測服務非常重要。為了更好地保障平臺和廣告主雙方的權益,以及為提升馬蜂窩旅遊網的廣告服務效果提供支撐,我們也在不斷地探索適合的解決方案,加強廣告監測服務的能力。
Part.1 初期形態初期我們的廣告監測並沒有形成完整的服務對外開放,因此實現方式及提供的能力也比較簡單,主要分為兩部分:一是基於客戶端打點,針對事件進行上報;另一部分是針對曝光、點選連結做轉碼存檔,當請求到來後解析跳轉。
但是很快,這種方式的弊端就暴露出來,主要體現在以下幾個方面:
收數的準確性:資料轉發需要訪問中介軟體才能完成,增加了多段丟包的機率。在和第三方監測服務進行對比驗證時,Gap 差異較大;資料的處理能力:收集的資料來自於各個業務系統,缺乏統一的資料標準,資料的多種屬性導致解析起來很複雜,增加了綜合資料二次利用的難度;突發流量:當流量瞬時升高,就會遇到 Redis 記憶體消耗高、服務掉線頻繁的問題;部署複雜:隨著不同裝置、不同廣告位的變更,打點趨於複雜,甚至可能會覆蓋不到;開發效率:初期的廣告監測功能單一,例如對實時性條件的計算查詢等都需要額外開發,非常影響效率。Part.2 基於 OpenResty 的架構實現在這樣的背景下,我們打造了馬蜂窩廣告資料監測平臺 ADMonitor,希望逐步將其實現成一個穩定、可靠、高可用的廣告監測服務。
2.1 設計思路為了解決老系統中的各種問題,我們引入了新的監測流程。主體流程設計為:
通過以上方式,使監測服務完全依賴 ADMonitor,極大地增加了監測部署的靈活性及整體服務的效能;同時為了進一步驗證資料的準確性,我們保留了打點的方式進行對比。
2.2 技術選型為了使上述流程落地,廣告監測的流量入口必須要具備高可用、高併發的能力,儘量減少非必要的網路請求。考慮到內部多個系統都需要流量,為了降低系統對接的人力成本,以及避免由於系統迭代對線上服務造成干擾,我們首先要做的就是把流量閘道器獨立出來。
關於 C10K 程式設計相關的技術業內有很多解決方案,比如 OpenResty、JavaNetty、Golang、NodeJS 等。它們共同的特點是使用一個程序或執行緒可以同時處理多個請求,基於執行緒池、基於多協程、基於事件驅動+回撥、實現 I/O 非阻塞。
我們最終選擇基於 OpenResty 構建廣告監測平臺,主要是對以下方面的考慮:
第一,OpenResty 工作在網路的 7 層之上,依託於比 HAProxy 更為強大和靈活的正則規則,可以針對 HTTP 應用的域名、目錄結構做一些分流、轉發的策略,既能做負載又能做反向代理;
第二,OpenResty 具有 Lua協程+Nginx 事件驅動的「事件迴圈回撥機制」,也就是 Openresty 的核心 Cosoket,對遠端後端諸如 MySQL、Memcached、Redis 等都可以實現同步寫程式碼的方式實現非阻塞 I/O;
第三,依託於 LuaJit,即時編譯器會將頻繁執行的程式碼編譯成機器碼快取起來,當下次呼叫時將直接執行機器碼,相比原生逐條執行虛擬機器指令效率更高,而對於那些只執行一次的程式碼仍然可以逐條執行。
2.3 架構實現整體方案依託於 OpenResty 的處理機制,在伺服器內部進行定製開發,主要劃分為資料收集、資料處理與資料歸檔三大部分,實現非同步拆分請求與 I/O 通訊。整體結構示意圖如下:
我們將多 Woker 日誌資訊以雙端佇列的方式存入 Master 共享記憶體,開啟 Worker 的 Timer 毫秒級定時器,離線解析流量。
2.3.1 資料收集收集部分也是主體承受流量壓力最大的部分。我們使用 Lua 來做整體檢參、過濾與推送。由於在我們的場景中,資料收集部分不需要考慮時序或對資料進行聚合處理,因此核心的推送介質選擇 Lua 共享記憶體即可,以 I/O 請求來代替訪問其他中介軟體所需要的網路服務,從而減少網路請求,滿足即時性的要求,如下所示:
下面結合 OpenResty 配置,介紹一些我們對伺服器節點進行的優化:
設定 lua 快取-lua_code_cache:(1)開啟後會將 Lua 檔案快取到記憶體中,加速訪問,但修改 Lua 程式碼需要 reload(2)儘量避免全域性變數的產生(3)關閉後會依賴 Woker 程序中生成自己新的 LVM設定 Resolver 對於網路請求、好的 DNS 節點或者自建的 DNS 節點在網路請求很高的情況下會很有幫助:(1)增加公司的 DNS 服務節點與補償的公網節點(2)使用 shared 來減少 Worker 查詢次數設定 epoll (multi_accept/accept_mutex/worker_connections):(1)設定 I/O 模型、防止驚群(2)避免服務節點浪費資源做無用處理而影響整體流轉等設定 keepalive:(1)包含連結時長與請求上限等配置優化一方面是要符合當前請求場景,另一方面要配合 Lua 發揮更好的效能。設定 Nginx 伺服器引數基礎是根據不同作業系統環境進行調優,比如 Linux 中一切皆檔案、調整檔案開啟數、設定 TCP Buckets、設定 TIME_WAIT 等。
2.3.2 資料處理這部分流程是將收集到的資料先通過 ETL,之後建立內部的日誌 location,結合 Lua 自定義 log_format,利用 Nginx 子請求特性離線完成資料落盤,同時保證資料延遲時長在毫秒級。
對被解析的資料處理要進行兩部分工作,一部分是 ETL,另一部分是 Count。
(1)ETL
主要流程:
日誌經過統一格式化之後,抽取包含實際意義引數部分進行資料解析將抽取後的資料進行過濾,針對整體字符集、IP、裝置、UA、相關標籤資訊等進行處理將轉化後的資料進行重載入與日誌重定向【例】Lua 利用 FFI 通過 IP 庫解析 "ip!"用 C 把 IP 庫拷貝到記憶體中,Lua 進行毫秒級查詢:
(2)Count
對於廣告資料來說,絕大部分業務需求都來自於資料統計,這裡直接使用 Redis+FluxDB 儲存資料,以有下幾個關鍵的技術點:
RDS 結合 Lua 設定連結時間,配置連結池來增加連結複用RDS 叢集服務實現去中心化,分散節點壓力,增加 AOF與延時入庫保證可靠FluxDB 保證資料日誌時序性可查,聚合統計與實時報表表現較優2.3.3 資料歸檔資料歸檔需要對全量資料入表,這個過程中會涉及到對一些無效資料進行過濾處理。這裡整體接入了公司的大資料體系,流程上分為線上處理和離線處理兩部分,能夠對資料回溯。使用的解決方案是線上 Flink、離線 Hive,其中需要關注:
實時資料來源:資料採集服務→ Filebeat → Kafka → Flink → ES
離線資料來源:HDFS → Spark → Hive → ES
資料解析後的再利用:
解析後的資料已經擁有了重複利用的價值。我們的主要應用場景有兩大塊。
一是 OLAP,針對業務場景與資料表現分析訪問廣告的人群屬性標籤變化情況,包含地域,裝置,人群分佈佔比與增長情況等;同時,針對未來人群庫存佔比進行預測,最後影響到實際投放上。
另一部分是在 OLTP,主要場景為:
判定使用者是否屬於廣告受眾區域解析 UA 資訊,獲取終端資訊,判斷是否屬於為低階爬蟲流量裝置號打標,從 Redis 獲取實時使用者畫像,進行實時標記等2.4 OpenResty 其他應用場景OpenResty 在我們的廣告資料監測服務全流程中均發揮著重要作用:
init_worker_by_lua階段:負責服務配置業務access_by_lua階段:負責CC防護、許可權准入、流量時序監控等業務content_by_lua階段:負責實現限速器、分流器、WebAPI、流量採集等業務log_by_lua階段:負責日誌落盤等業務重點解讀以下兩個應用的實現方式。
2.4.1 分流器業務NodeJS 服務向 OpenResty 閘道器上報當前伺服器 CPU 和記憶體使用情況;Lua 指令碼呼叫 RedisCluster 獲取時間視窗內 NodeJS 叢集使用情況後,計算出負載較高的 NodeJS 機器;OpenResty 對 NodeJS 叢集流量進行熔斷、降級、限流等邏輯處理;將監控資料同步 InfluxDB,進行時序監測。
2.4.2 小型 WEB 防火牆使用第三方開源 lua_resty_waf 類庫實現,支援 IP 白名單和黑名單、URL 白名單、UA 過濾、CC 攻擊防護功能。我們在此基礎上增加了 WAF 對 InfluxDB 的支援,進行時序監控和服務預警。
2.5 小結總結來看,基於 OpenResty 實現的廣告監測服務 ADMonitor 具備以下特點:
高可用:依賴 OpenResty 做 Gateway, 多節點做 HA立即返回:解析資料後利用 I/O 請求做資料非同步處理,避免非必要的網路通訊解耦功能模組:對請求、資料處理和轉發實現解耦,縮減單請求序列處理耗時服務保障: 針對重要的資料結果利用第三方元件單獨儲存完整的技術方案示意如下:
Part.3 總結
目前,ADMonitor 已經接入公司的廣告服務體系,總體執行情況比較理想:
1. 效能效果達到了高吞吐、低延遲的標準轉發成功率高,曝光計數成功率>99.9%,點選成功率>99.8%2. 業務效果與主流第三方監測機構進行資料對比:曝光資料 GAP < 1%,點選資料GAP < 3%可提供實時檢索與聚合服務未來我們將結合業務發展和服務場景不斷完善,期待和大家多多交流。