1. 程式人生 > >APP 精細化 HTTP 分析 (一):別再只是代理抓個包了

APP 精細化 HTTP 分析 (一):別再只是代理抓個包了

HTTP/REST是目前最主流的前後端介面設計,在測試、線上環境裡截獲HTTP請求可以有效診斷介面請求錯誤、響應效能、網路環境對頁面響應的影響、使用者路徑分析等。本文從截獲APP HTTP請求開始講起,介紹如何分析錯誤的HTTP響應,以及分析響應的效能,穿插實戰中找到的問題案例。系列文章將一步步介紹精細化分析。

截獲APP HTTP請求響應

從代理抓包到插樁截獲

APP端和伺服器端的互動是非常重要的一個環節,能夠獲取互動資訊可以有效提高測試分析的效率,找到服務端的問題、定位APP程式碼問題,甚至用來分析使用者路徑、流量等,是提高產品質量的重要工具。

說到HTTP抓包,第一個想到的肯定是代理軟體,例如Charles和Fiddler,搜一下,教程很多,用過之後缺點非常多:

  • 架設代理需要修改裝置系統配置(還考慮到https偽造證書),自動化起來很麻煩,尤其考慮到裝置多樣性
  • 代理裝在開發機上是全流量(電腦上的各種,裝置的系統,推送等),還要過濾出APP的
  • 代理很多場景不適應,例如測試網路切換,使用者那邊也不可能掛代理
  • 代理軟體天生是給人看的,匯出資料做進一步分析也很人工費事

理想的情況應該是在APP內部有一個機制截獲APP的HTTP請求響應,log下來,然後能夠方便獲取做進一步分析。這樣一來APP自然就會log自己的流量;同時因為是APP內部,所以https不再是問題;資料可以靈活獲取、分析;而且可以根據不同配置(測試環境、使用者環境)採取不同的log策略,用來不同的分析(測試時全log,分析錯誤、效能、穩定性等;使用者環境打點、報告問題請求響應)。

然而只有有些HTTP庫,比如okhttp,提供了比較方便的log介面(Interceptor),很多http請求都沒有這樣的log介面。另外APP自己會用很多三方庫裡也會發出請求,三方庫程式碼不好改。最後,監控點如果需要人工維護,成本也很高。

Appetizer 通過插樁技術解決這以上所有問題,插樁是對APK的位元組碼(Dex檔案)進行修改,根據規則截獲APP以及三方庫內傳送的HTTP請求,並log HTTP請求和響應,相比系統代理,插樁截獲有以下優勢:

  • 一鍵插樁 APK即具備http log功能,不需要修改裝置配置,插樁可以指令碼操作,接入Jenkins等
  • 插樁截獲 APK本身流量,不用過濾
  • 插樁截獲靈活度高,可以進行配置選擇性截獲,可以廣泛應用於測試以及線上環境
  • 插樁截獲的資料完整,可以用來進行高階的分析

APP常用HTTP庫

APP中常用的HTTP請求庫有HttpURLConnection(HUC), Apache HTTP Client, OkHttp, Retrofit, Volley,還有一些“快速開發框架”(實際內部封裝了這些庫)。HUC是java.net.HttpURLConnection提供的功能,是Java自帶的標準庫,通常是第三方庫用來請求HTTP的(這樣就可以只依賴標準庫)。Apache是曾經Android推薦的HTTP庫,從5.0開始已經不再推薦,不過有一些老的三方庫、控制元件庫依然使用著Apache。OkHttp 是Square公司開發的方便好用的現代的HTTP請求庫,目前使用非常流行,Retrofit也是依賴於OkHttp,OkHttp有2.x (包名com.squareup.okhttp), 3.x(包名okhttp3.*)兩個版本,從5.0+開始,標準庫的HUC實際內部實現是okhttp。最後Volley是Google官方出的一套小而巧的非同步請求庫,
其實是個框架,底層可以對接其他HTTP庫,官方提供了Apache和HttpURLConnection的支援。此外國內外有很多“所謂的HTTP庫”其實都是對這幾個庫的封裝。

下圖總結了一下常見的庫的依賴關係,還有一些比較上層的封裝庫和開發框架:

Appetizer 截獲原理

Appetizer本身通過位元組碼插樁的方式來截獲APP呼叫HTTP庫的API。Appetizer截獲最底層的HUC, Apache和okhttp 2.x和3.x,從而支援所有依賴於這幾個底層庫的框架,如果有我們沒有提到的HTTP庫,請在評論區告知。
對於okhttp 截獲比較簡單,因為okhttp提供了天然的Interceptor介面,Appetizer如果探測到APP使用了okhttp,則在程式開頭註冊一個自己的interceptor。而Apache HTTP Client和HUC就沒有這麼方便的機制,於是Appetizer會掃描整個APP的程式碼,為每處呼叫加上log程式碼,例如:

URLConnection conn = new URL("https://appetizer.io").openConnection();
// Appetizer搜尋到openConnection 的呼叫,在這裡插入log程式碼,記錄conn的內容(請求頭、響應內容等)
conn.getResponseCode();

精細化HTTP分析(一):後端介面錯誤分析

插樁技術相比較於需要接入SDK的方式(比如Facebook Stetho和一些監控庫)有以下優點:

  • 基於插樁規則,完全自動,沒有接入和後期維護監控點的成本
  • 全面,不僅覆蓋是App程式碼,而且覆蓋所有的庫程式碼,即使這些三方庫用了老的API
  • 測量邏輯和APP業務邏輯解耦和,一鍵插樁加測量,一鍵關閉

有了截獲的HTTP資料後,我們可以開始分析,精細化HTTP分析對於開發、測試以至於產品分析都有非常重要的用處。我們會分幾期介紹基於HTTP資料的各種分析。

最常見的是對錯誤返回碼系列的分析,4xx是client端的問題,5xx是server端的問題。

對於4xx的返回碼(如下圖),Appetizer會給出完整的請求URL(包括請求引數),以及請求Header(見摺疊),通常這類情況是由於構造的的URL有問題,例如引數問題,或者是一些字串轉碼方面的問題。Appetizer 1.2.0推出後,報告頁面右上角會多一個按鈕,用於匯出這個問題請求的cURL 命令列,可以輕鬆匯入postman進行進一步測試


如果返回碼是5xx,那就是後端同學的鍋了,同樣,可以產生了cURL命令列發給後端同學去反覆測試這個介面。

常見問答

  • 除了GET,POST,其他HTTP 方法,比如PUT支援嗎?

    我們支援HTTP協議支援的所有HTTP方法,包括更為小眾的PATCH (例如zhihu用了),HEAD等。所以只要是REST API都可以用Appetizer來截獲分析。

  • APP可以加固麼?

    不可以,加固後的APP不能修改,開發包可以考慮只混淆

  • APP可以混淆麼?

    插樁本身支援混淆後的APP,但是有些截獲功能是通過尋找目標庫的API實現的,混淆後有些庫的API被去除或者改名會導致部分庫無法識別,無法截獲。目前如果使用了okhttp,最好保證庫不會被混淆,可以在proguard規則中增加:

    -keepattributes Signature
    -keepattributes Annotation
    -keep class okhttp3.** { *; }
    -keep interface okhttp3.** { *; }
    -dontwarn okhttp3.**
    -dontwarn okio.**
    
  • ReactNative/Weex等H5技術開發的APP支援麼?

    經測試是完全支援的。ReactNative的HTTP庫用的是OkHttp,在我們支援範圍內。

  • Kotlin 開發的APP支援麼?

    經測試是完全支援的。

  • webview控制元件裡的頁面請求能截獲嗎?

    正在開發中

  • 插樁截獲功能對效能的影響怎樣?

    插樁程式碼的執行代價是記錄HTTP請求,Appetizer只記錄請求響應的header內容,並不記錄body,從而效能影響很小,記錄單個請求耗時最多1ms。同時,因為HTTP請求都是在APP的子執行緒上完成的,所以不會造成任何主執行緒卡頓

  • 使用了一些會發出HTTP請求的C++庫(.so)能截獲嗎?

    目前不支援,插樁僅限Java程式碼。例如使用了Lua 直譯器、C++的視訊/音訊播放器目前都暫不支援,如果希望支援,請在評論區留言

  • 支援手遊嗎?

    同上。手遊的HTTP是從C++庫裡發出的

  • 支援非HTTP協議,例如RTP之類的

    暫不支援

  • iOS呢?

    參考光哥的文

預告

  • 精細化HTTP分析(二):響應效能分析與優化
  • 精細化HTTP分析(三):流量分析
  • 精細化HTTP分析(四):弱網響應下介面穩定性分析
  • 精細化HTTP分析(五):通過複雜Query定製HTTP分析報告
  • 更多需求,請在評論區提議