大數據

Android網絡性能監控方案

阿里雲 雲原生應用研發平臺EMAS 劉寶文(木睿)

背景

移動互聯網時代,移動端極大部分業務都需要通過App和Server之間的數據交互來實現,所以大部分App提供的業務功能都需要使用網絡請求。如果因為網絡請求慢或者請求失敗,導致用戶無法順暢的使用業務功能,會對用戶體驗造成極大影響。

此外,EMAS對外提供的APM之前並不包括網絡監控功能,而網絡性能監控作為移動端性能監控的重要組成部分,我們急需補全這部分能力來完善APM的產品功能,進一步滿足客戶的需求。

“阿里巴巴應用研發平臺 EMAS 是國內領先的雲原生應用研發平臺(移動App、H5應用、小程序、Web應用等),基於廣泛的雲原生技術(Backend as a Service、Serverless、DevOps、低代碼等),致力於為企業、開發者提供一站式的應用研發管理服務,涵蓋開發、測試、運維、運營等應用全生命週期。”

問題與挑戰

網絡性能監控在端上主要包括數據採集和數據上報。我們希望能儘可能採集有用的信息來幫助客戶發現、定位和解決網絡性能問題。我們面臨如下問題和挑戰:

•首先要解決的是網絡請求過程中,哪些階段會影響請求性能,如果發現網絡性能有問題,需要採集哪些數據來幫助用戶去定位和解決問題。

• android上主流的網絡框架有okhttp2、okhttp3、okhttp4、volley、retrofit、httpclient和系統提供的httpurlconnection等,在我們不確定客戶使用哪個網絡庫的哪個版本的情況下,如何儘量採集有用的信息。

• 網絡請求各個階段的數據採集都是離散的,如何保證單個請求各個離散的監控數據能夠串聯起來,不和其他請求的監控數據混在一起。

• 由於弱網環境下的網絡請求日誌往往更有價值,需要儘可能將異常的網絡請求日誌數據上報到服務端。

• 併發網絡請求時,需要確保在日誌上傳時儘量不影響客戶正常業務。

實現方案

網絡性能監控在端上的具體實現主要包含兩大模塊:
• 數據採集
• 數據上報
其中數據採集是整個SDK框架的核心。

整體架構概覽:

image.png

接入層:
網絡監控屬於高可用產品的一部分,採用高可用統一接入的方式接入。
插件層:
高可用目前框架是通過插件式的方式集成各個業務,實現networkmonitor plugin集成到APM中,補充APM中網絡監控部分。
邏輯層:
主要負責採集控制、數據管理、緩存管理和數據上報。
攔截器層:
整個網絡監控的核心。為了採集更多的信息,我們選擇使用字節碼注入技術來實現網絡請求監控功能。對OkHttp、HttpClient和HttpUrlConnection,分別實現Interceptor去採集不同網絡庫中網絡請求各個階段的數據,並在請求結束時完成採集進行上報。此外,通過自定義gradle plugin的方式,為各個網絡庫實現Injector和開關,控制在應用構建階段將Interceptor中各個採集的方法注入到對應網絡庫字節碼的埋點位置,從而實現在運行時網絡請求各個階段採集需要的數據。

數據採集

採集哪些數據

首先需要確定採集的數據範圍來幫助我們及時發現網絡請求的性能和異常等情況,另一方面也需要有額外的數據來輔助排查問題。所以我們採集的數據主要包括四個部分:
• 基礎數據。
• 性能數據。
• 異常信息。
• 事件序列數據。

基礎數據

image.png

• 請求url:對請求做聚合運算。
• 目標IP地址:對於多出口IP的客戶,支持IP地址維度的數據分析。
• dns解析結果:請求url的域名解析ip列表,用於分析是否存在域名劫持的問題。
• http code:根據http code確定請求狀態。
• 上行流量:包括整個請求上行header和body的總的流量,包含重試和重定向的上行流量。用於監控上行流量開銷。
• 下行流量:包括整個請求下行header和body的總的流量,包含重試和重定向的下行流量。用於監控下行流量開銷。
• 網絡庫類型及版本:對於客戶更換網絡庫或者升級網絡庫版本的情況,可以提供前後的網絡數據的差異。

性能數據

性能數據主要是採集整個網絡請求中各個階段的耗時情況來定位慢請求發生的階段。下圖列舉了http請求可能出現的各個階段。

image.png

所以性能數據部分需要採集下述各個階段的耗時數據:

  • •整個網絡請求耗時
    • •dns耗時
    • •建連耗時
      • •TLS建連耗時
    • •數據上行耗時
      • •header上行耗時
      • •body上行耗時
    • •數據下行耗時
      • •header下行耗時
      • •body下行耗時

異常信息

異常信息主要是收集網絡請求各階段出現異常時的異常棧的信息。比如常見的java.net.UnknownHostException、java.net.SocketTimeoutException等。

事件序列數據

事件序列數據主要是收集網絡請求各階段的監控事件的信息,另外對於特定網絡庫的一些特殊的事件的監控,比如okhttp的連接複用、自動重定向和失敗重試等對網絡耗時有影響的機制。最後將這些事件按時間順序排列。

比如在okhttp上dns被劫持的場景,我們通過基礎數據中的目標IP地址去判斷dns劫持情況,這個目標IP地址是在建立連接的時候去採集的。如果第一個請求發生了dns劫持的情況,那這個請求我們能正常識別的dns劫持已經發生。如果後續的網絡請求複用了這個連接,因為不會再去建立連接,所以基礎數據中沒有目標IP地址,這時候就需要使用事件序列數據中的連接複用事件中的連接的url和目標IP地址來判斷是不是被劫持的請求。

如何採集數據

字節碼插樁原理

字節碼插樁涉及到Android的打包構建流程。首先我們看下Android應用程序的打包流程,如下圖:

image.png

從上圖可知,我們只需要在 javac 之後 dex 之前遍歷所有的字節碼文件,並按照一定的規則過濾修改就可以實現字節碼的插樁。

從Android Gradle 1.5.0 開始,Google官方提供了Transform API。通過Transform API,允許第三方以插件的形式,在Android應用程序打包成dex文件之前的編譯過程中操作.class文件。

image.png

Android編譯器中的TaskManager將每個Transform串起來,第一個Transform接收來自javac編譯的結果,以及已經拉取到本地的第三方sdk(jar、aar),還有resource資源。這些編譯的中間產物,在Transform組成的鏈條上流動,每個Transform節點可以對class進行處理再傳遞給下一個Transform。常見的混淆、Desugar等的實現就是封裝在一個個Transform中。而自定義的Tranform會插入到這個Transform鏈條的最前面,所以開啟混淆的情況下通過自定義Transform對字節碼進行修改也是先修改字節碼再混淆。

網絡庫調研

除了系統自帶的網絡庫HttpUrlConnection,在android平臺還有很多優秀的第三方網絡庫,大部分App開發會使用第三方的網絡庫來發起網絡請求。

image.png

從上表中主流網絡庫的底層實現來看,我們只要支持OkHttp、HttpUrlConnection和HttpClinet的數據採集就能滿足主流網絡庫的性能監控需求。

image.png

我們對應用市場上Top1000的App進行了分析,按集成數量排序依次是okhttp3&okhttp4、volley(HttpUrlConnection)、okhttp2和httpclient。其中okhttp網絡庫佔比將近80%,所以我們優先實現了okhttp網絡庫的監控實現。

okhttp網絡庫的監控實現

okhttp網絡庫家族主要包括okhttp2、okhttp3和okhttp4。其中okhttp3版本分佈眾多,底層實現變化也最多,而okhttp2的底層實現和okhttp3的早期版本相近,okhttp4是okhttp3的kotlin版本的實現。所以我們主要介紹下okhttp3上的監控實現。

image.png

上圖是okhttp3.12.0版本的實現框架,我們在網絡庫的具體邏輯裡注入代碼來採集需要的數據。

okhttp3版本眾多,從3.0.0-3.14.9已經有超過40個版本,對於每一個代碼注入的位置都需要確保再各個版本上能正常工作。所以實現okhttp3的無痕埋點,版本適配需要耗費大量的工作。

數據上報

數據上報,除了需要考慮加密、鑑權、壓縮等方面,還需要能確保儘可能少的丟失日誌,同時還需要控制資源的佔用來降低對上層業務的影響。具體實現主要包括兩方面:

• 緩存:支持內存緩存和磁盤緩存兩級緩存。需要實現業務隔離,多個業務使用緩存功能時可以做到互不影響。
• 上報:由於APM產生的日誌較多,為了控制併發數和內存,我們使用了一個業務共享的線程池和調度隊列。調度隊列最多緩存10條批量日誌,如果超出10條會立即將日誌放入磁盤緩存。另外在上報前提供了日誌預處理的開放接口方便業務層對日誌做處理,比如抽樣、聚合等功能。

後續計劃

EMAS網絡性能監控已經對外開放,產品詳情:https://www.aliyun.com/product/emascrash/apm 後續我們會根據客戶實際需求去逐步完善功能。下一步計劃實現的需求包括:
• 支持HttpUrlConnection、HttpClient等網絡庫。
• 支持body數據的採集上報,讓客戶可以感知、定位和解決在網絡連通性正常,但服務端下發異常數據導致端上業務出現異常的問題。
• 支持日誌數據端上預聚合,降低服務端存儲壓力。
• 支持socket請求的監控。

歡迎大家積極留言,提出你們的寶貴意見和建議,非常感謝!釘釘搜索35248489,加入阿里云云原生應用研發平臺EMAS技術交流群,探討最新最熱門的應用研發技術和實踐。

Leave a Reply

Your email address will not be published. Required fields are marked *