Analyze HTTP traffic in Instruments

前言

今天和大家分享WWDC2021的HTTP流量分析的技術(shù)界逛,通常我們會在一些抓包工具里處理自己的應(yīng)用網(wǎng)絡(luò)數(shù)據(jù)分析
那么。但是,這些工具如何和我們的代碼結(jié)合在一起呢咏窿,WWDC2021引入了新的HTTP traffic in Instruments,如圖


HTTP Traffic Instrument

我們可以看到素征,還是很像之前的Network工具的集嵌。
實際上萝挤,今天介紹的13版本工具集中的HTTP 流量工具它包含在之前的Network模版中,可以幫助我們理解API和請求生命周期的關(guān)系

  1. 它適用于所有蘋果設(shè)備
  2. 整個穿過URL 加載系統(tǒng)的流量都會曝光纸淮、甚至是HTTP/3或者是VPN
  3. 以framework級別集成在系統(tǒng)中
    ○ 過程以屬性方式表達(dá)
    ○ 磁盤緩存請求
    ○ 揭示網(wǎng)絡(luò)錯誤
    ○ 熟悉的高層API

篇章結(jié)構(gòu)

介紹的內(nèi)容分兩部分:
第一部分:主要解釋工具的UI如何反映你正在使用的API內(nèi)容
第二部分:通過4個例子來解決性能和正確性問題

第一部分: 工具UI概覽

HTTP Traffic Instrument

首先介紹導(dǎo)航平斩,導(dǎo)航是圍繞軌跡堆棧構(gòu)建的
HTTP流量工具在最頂層(紅色區(qū)域),展示任意時間APP中有多少任務(wù)咽块,非常適合在應(yīng)用程序生命周期中檢測HTTP流量活動增加的點绘面。
下一層次結(jié)構(gòu)(綠色區(qū)域)顯示了按進程劃分的活動。 不僅有所有可調(diào)試的過程產(chǎn)生的流量侈沪,還有由它們初始化的后臺流量
每個進程下面都包含它使用的所有URLSession揭璃。這些對應(yīng)于在代碼中創(chuàng)建的URLSession對象。
橙色的這一部分是每個session和它們的獨立任務(wù)亭罪,為了更好的將代碼和可視化結(jié)合起來瘦馍,允許我們查看每個獨立的任務(wù)間隔,可以在代碼中將session實例命名应役,可以通過如下的代碼來實現(xiàn)
let session = URLSession(configuration: .default)
session.sessionDescription = "Main session”
最后一個是按照域名分類的任務(wù)信息情组,這里會展示任務(wù)的狀態(tài)
例如,上圖的藍(lán)色部分就是一些task 從選中的域名在加載數(shù)據(jù)

單個Task分析

我們來分析一個task


單個task的信息

這個任務(wù)間隔有很多的信息
我們可以以一個更抽象的方式來重新表示這張圖箩祥,來理解工具的可視化如何映射到使用的API
我們把它簡化成第二張圖


task信息抽象表示

最頂層的是一個task 也就是綠色的部分
Task 是由一個或者多個事務(wù)組成的 每個事務(wù)是由 一對HTTP請求和響應(yīng)組成的

任務(wù)API與UI對應(yīng)

API與UI的映射

Task 是代表了你的代碼如何與URL加載系統(tǒng)API進行交互 當(dāng)我們創(chuàng)建一個task 并調(diào)用它的resume方法院崇,這個task 間隔就開始了而當(dāng)你的completion Block被調(diào)用的時候這個間隔就結(jié)束了
每個task都可以給一個semantic語義名稱,通過使用taskDescription屬性袍祖,這個屬性會在工具中來標(biāo)記任務(wù)間隔

任務(wù)描述

任務(wù)label的描述

每個task都可以給一個semantic語義名稱通過使用taskDescription屬性 這個屬性會在工具中來標(biāo)記任務(wù)間隔

任務(wù)標(biāo)識

任務(wù)label的標(biāo)識

同時我們也會在task label 上顯示task的identifier 這允許我們將任務(wù)與其他數(shù)據(jù)交叉引用

任務(wù)發(fā)生錯誤

任務(wù)label描述錯誤

當(dāng)任務(wù)失敗的時候底瓣,錯誤的提示會打印在間隔的label上 這使得我們更容易調(diào)試 下面我們來看 一個任務(wù)包含多個事務(wù)的情況

Task 有多個事務(wù)

包含多個事務(wù)的task

這是一個加載APP首頁的任務(wù) 左邊我們請求了一個apple.com 但是實際上它的網(wǎng)址是 www.apple.com 這個時候服務(wù)器返回重定向,系統(tǒng)會重新初始化一個新事務(wù)以加載首選URL 第二個成功的響應(yīng)就是task的返回
它與URLSession在底層處理任務(wù)的功能一致

任務(wù)Label內(nèi)容的結(jié)構(gòu)

任務(wù)Label內(nèi)容

如前所述:任務(wù)Label表示了URL加載系統(tǒng)處理的請求 + 響應(yīng)對
其中包含了所有的HTTP層的信息:
URL, HTTP版本,連接,緩存信息
請求 + 響應(yīng)頭
請求 + 響應(yīng)體

Transaction 信息概要

Transaction信息概要

就像任務(wù)一樣蕉陋,事務(wù)的label也是展示一個概要捐凭,基本上,我們可以找到請求和響應(yīng)兩部分凳鬓,導(dǎo)航結(jié)構(gòu)會顯示域名茁肠,可以在請求部分找到路徑、請求參數(shù)缩举, 例子中的信息依次是HTTP的version垦梆、method、請求里是否攜帶了認(rèn)證頭部和cookie 頭部蚁孔。對于響應(yīng)奶赔,我們會看到 status code 例如上面的200 ,還有響應(yīng)里是否攜帶了set-cookie 頭部杠氢,最后是content-type的內(nèi)容站刑。 請求和響應(yīng)花費了多長時間。以及關(guān)于事務(wù)其他部分的詳細(xì)時間信息都會在存儲在事務(wù)的狀態(tài)里鼻百。接下里我們分析一下這個內(nèi)容

不同階段的時間

事務(wù)不同階段的時間

Transaction 的起始是transaction被創(chuàng)建的時候绞旅。 它首先會檢查我們是否已經(jīng)有了一個合法的緩存如果沒有摆尝,它就會在一個connection上開始一個新的請求,接下來 transaction 可能會等待一段時間來等一個可用的連接因悲, 當(dāng)請求被連接處理之后堕汞,發(fā)送請求的階段就開始了,這一階段持續(xù)到我們把請求的最后一個比特發(fā)送出去 然后transaction 進入一個空閑的狀態(tài)晃琳,等待響應(yīng)然后接收響應(yīng)讯检,該響應(yīng)將跟蹤從服務(wù)器收到的第一個字節(jié)到最后一個字節(jié)的跨度,整個事務(wù)將在收到最后一個字節(jié)后的很短時間內(nèi)結(jié)束
事實上卫旱, 緩存查找和發(fā)送一個GET請求要比圖中短很多 所以實際上的時間段看起來就像這樣


實際的事務(wù)不同階段時間

接下來我們進入第二部分:實例

第二部分:實例

用HTTP Traffic工具驗證APP

讓我們來用HTTP Traffic工具驗證下APP來幫助我們改善這種狀況 在Product菜單中我選擇Profile來在工具中分析APP 這會使用release 配置人灼,開啟了全部的優(yōu)化來構(gòu)建我的APP,以確保我的應(yīng)用程序能夠像我用戶運行的那樣進行評測顾翼。 構(gòu)建完成后投放,工具會自動啟動,啟動后就會看到標(biāo)準(zhǔn)的工具選擇界面适贸,我們選擇Network模版


使用Profile驗證APP

Network 面板

Network面板

下邊的是已有的流量分析工具灸芳,上邊是新的HTTP Traffic工具。我們主要集中在上邊這個工具 只要我們點擊record 工具就會啟動APP并開始記錄拜姿,當(dāng)然 開始使用這個工具之前需要確認(rèn)你理解捕獲網(wǎng)絡(luò)流量的含義 工具會抓獲很多數(shù)據(jù)尤其是你決定捕獲所有進程 即使是用戶憑據(jù)烙样,所以你應(yīng)該對結(jié)果追蹤文件非常小心

顯示所有的事務(wù)間隔

接著讓我們使用option click 和拖動放大數(shù)據(jù)確保包含我們HTTP traffic的區(qū)域


展開追蹤區(qū)域

我們也可以像圖片一樣在左側(cè)點擊向下展開,增加追蹤區(qū)域的高度砾隅,來顯示所有的事務(wù)間隔

實例1

想象我們有一個專門展示圖片的類似社交媒體的APP误阻,用戶可以上傳圖片债蜜,并且獲得一連串最近的上傳圖片 當(dāng)加載一系列圖片的時候晴埂,我們會注意到等全部加載完會花費一些時間,為了分析這個問題我們打開HTTP Traffic面板

列表加載過程.png

在這張圖片上 左側(cè)的第一個是請求服務(wù)器最近圖片列表的任務(wù)寻定,當(dāng)這個任務(wù)完成后 我們會創(chuàng)建一個新的任務(wù)儒洛,加載列表中每個用戶看到的(thumbnail)縮略圖 現(xiàn)在在它所占用的時間幀區(qū)域上點擊拖動來獲取圖像列表 這后邊會跟著許多請求來獲取每個圖片
查看整個過程的耗時

如圖當(dāng)我們拖動的時候會顯示選擇的時間范圍總共多長時間, 可以看到整個過程占用了超過7秒鐘來完成加載初始化的屏幕
事務(wù)的完成時間

前面的一些圖片加載比較快狼速,但當(dāng)我向下滾動琅锻,后面啟動的任務(wù)完成所需的時間會更長
這從圖中增長的紫色blocked狀態(tài)條可以看出。
看起來像是因為競爭問題向胡,我們這里有太多的并行的請求恼蓬,我們不妨探究一下后邊的某個任務(wù) 鼠標(biāo)懸停在上邊就可以看到工具的關(guān)于任務(wù)和它任何子環(huán)節(jié)的時間間隔提示 可以看到這個任務(wù)大部分時間都被阻塞了
為了理解為什么被阻塞了,我們可以查看左側(cè)域名下的向下展開的箭頭
選擇 HTTP Transactions by Connection項

如圖所示僵芹,可以看到當(dāng)前選擇的是繪制任務(wù)处硬, 我們切換到 HTTP Transactions by Connection
HTTP Transactions by Connection視圖

這個視圖將事務(wù)按照它們使用的連接而不是按照任務(wù)來將它們分類 我們可以找出它們被調(diào)度到哪個連接 總體上,這里有6個連接可以處理這些事務(wù)拇派,我們來分析connection1上的事務(wù)問題荷辕,并進一步探索一些縮略圖的加載
從上而下事務(wù)完成的時間越來越長凿跳, 每個成功的事務(wù)的紫色阻塞狀態(tài)都在增加 事實上,這里有一個很清晰的階梯部分在這里
事務(wù)的階梯完成狀態(tài)

每一個任務(wù)都會在同一個連接的之前的事務(wù)完成之前等待疮方。只有這樣才能發(fā)送它自己的請求控嗜,也就是圖中每一個事務(wù)的灰色部分的開始和上一個的灰色部分的結(jié)束是對齊的,這個模式會在每一個后續(xù)的事務(wù)上重復(fù)骡显, 這也就是我們說的線路阻塞疆栏,這也是使用HTTP1的問題。令人沮喪的是惫谤,這些事務(wù)大部分時間都不做任何事情承边,它們大部分時間都在阻塞和等待服務(wù)器的響應(yīng),我們可以在事務(wù)等待同一個連接的上一個事務(wù)的請求響應(yīng)的時候發(fā)送新的請求 石挂,但是HTTP1并不支持這些博助,線路阻塞是http的主要問題之一,http的主要提升就是一個連接上向服務(wù)器發(fā)送多個請求痹愚。
iOS15之后工具也開始支持http3了
線路阻塞

使用http1的事務(wù)完成圖

使用HTTP/2解決阻塞問題

使用HTTP/2的事務(wù)完成狀態(tài)

這是我們改為使用http/2之后的效果富岳,可以看到這里沒有明顯的阻塞狀態(tài)了
我們再次回顧一下 HTTP Transaction by connection 面板,我們可以注意到這里只有一個連接拯腮, 這是因為我們不再需要多個連接來發(fā)送并發(fā)的請求了窖式。這也意味著我們只有一次連接建立的損耗 我們也能注意到可以在事務(wù)等待同一個連接的上一個事務(wù)的請求響應(yīng)的時候發(fā)送新的請求 我們可以看到請求都在很短時間內(nèi)發(fā)送出去,只剩下等待服務(wù)器響應(yīng)了 我們往下滾動也可以看到动壤,所有的等待都是同時開始的

實例2

假如我們APP有一個需要登錄的功能萝喘,登錄之后用戶就可以不用登錄了


登錄請求過程

這是之前記錄的一個追蹤文件 我們可以用工具打開它并分析 左側(cè)是我點擊某個按鈕時候的任務(wù) 第一個任務(wù)間隔包含兩個事務(wù) 最后一個是對應(yīng)我的第二次put請求


第一個登錄請求

放大之后我們可以看到,第一個請求得到了一個401的狀態(tài)碼 代表沒有訪問權(quán)限 這是我們預(yù)料到的琼懊。因為我們沒有登錄 這個事務(wù)被繪制成橙色來表示在http層這不是一個成功的事務(wù) 中間綠色的部分表示我們設(shè)備的網(wǎng)絡(luò)空閑了一段時間
然后我們看第二個事務(wù)
第二個登錄請求

當(dāng)我們進行操作來登錄的時候 我們會重試事務(wù) 201響應(yīng)碼表示請求已經(jīng)被成功處理,并且創(chuàng)建了新的資源 這次成功了 身份驗證質(zhì)詢的這種交互 輸入密碼 然后重試事務(wù) 是URL加載系統(tǒng)為我們處理的另外一種case


兩個事務(wù)的關(guān)系

所以之前的這兩個事務(wù)實際上屬于同一個任務(wù)
我們來看另外一個事務(wù)
第三個登錄請求

當(dāng)我正在進行請求的時候 我關(guān)閉了app頁面 這個任務(wù)整體是灰色的阁簸,代表被取消 事務(wù)的提示label 是橙色 代表又收到了401響應(yīng) 我們使用一個非常基礎(chǔ)的記錄系統(tǒng) 第一次的時候用戶發(fā)送它們的身份驗證 一旦服務(wù)器驗證了用戶身份它就會設(shè)置一個cookie 這樣用戶之后的請求就不用身份驗證了哼丈,我本以為這個任務(wù)會發(fā)送正確的cookie启妹, 讓我們驗證一下是否發(fā)送了,如前面介紹的 這里應(yīng)該有一個小的cookie 圖標(biāo)緊鄰著HTTP方法 但是這里沒有 這意味著沒有發(fā)送cookie 那么問題來了 是服務(wù)器沒有給我們提供cookie 還是客戶端得到了但沒有發(fā)送 為了找到原因 我們需要查看之前的事務(wù) 并檢查我們是否從服務(wù)器得到了一個cookie
失敗事務(wù)的前置事務(wù)

這是之前的一個事務(wù) 也就是登錄之后的一個成功請求 可以看到確實有一個cookie圖標(biāo)在響應(yīng)中醉旦, 所以服務(wù)器確實返回cookie了 那么我們?yōu)槭裁丛谙乱淮沃袥]有發(fā)送cookie呢 細(xì)節(jié)可以查看Transaction列表
transaction列表

然后我們查看detail面板
detail面板

可以看到我們期望的Set-Cookie Header 第一眼看上去這個cookie很正常但是 細(xì)看會發(fā)現(xiàn) 它的過期時間是 2020年饶米,在過去 ,所以這會導(dǎo)致URLSession 不發(fā)送cookie

實例3

有時车胡, 我們的網(wǎng)絡(luò)資源列表里會一些元素沒有正確顯示出來


列表加載的過程

比如看上面這張圖檬输,我們期望找到一個列表加載的過程,所以先選中域名匈棘,這里有很多的請求丧慈,注意到左下角的detail filter了嗎 我們可以在這里過濾


列表過濾的結(jié)果

選中并放大第一個請求的時間線
第一個請求

可以看到一切正常
但是當(dāng)我們向后滑動的時候,可以看到一個很短的請求羹饰。


持續(xù)時間較短的請求

繼續(xù)放大這個請求
時間線放大后的請求

可以看到這個請求持續(xù)了幾毫秒 這不是從服務(wù)器拿的請求
我們再次點擊 HTTP Transaction by connection 面板
HTTP Transaction by connection 面板

可以看到它并不是執(zhí)行在一個連接上伊滋,而是Local Cache 所以我們知道了我們的請求被緩存了 一個解決辦法是告訴服務(wù)器設(shè)置一個cache-control頭部碳却,不緩存這個請求 我們希望每次進入頁面都刷新列表,但是不希望在沒有改動的時候也加載整個列表笑旺。好的方法是我們詢問服務(wù)器是否有改動昼浦,并讓服務(wù)器告訴客戶端。 我們可以更改URLRequest 的cache-policy 如果這樣 服務(wù)器就會返回304 告訴我們使用本地緩存 如果更改了 就會返回新的數(shù)據(jù)

實例4

如果我們集成了一些SDK筒主,使用時候會發(fā)現(xiàn)关噪,集成的SDK在不期望網(wǎng)絡(luò)操作的時候就發(fā)出了網(wǎng)絡(luò)請求,


SDK在不期望的時候發(fā)出請求

我們同樣可以在detail面板來觀察代碼哪一部分做了網(wǎng)絡(luò)請求


網(wǎng)絡(luò)請求的詳細(xì)信息

從Detail可以看到確實是集成的SDK發(fā)出了網(wǎng)絡(luò)請求
當(dāng)我們向下滾動的時候
SDK的請求的位置信息

看起來像是 Core Location被激活了 這是非澄诿睿可疑的使兔,尤其是我并沒有用任何操作來觸發(fā)它。我們可能會想藤韵,我的位置是否上傳到了服務(wù)器虐沥,因為CoreLocation和CFNetwork同時存在, 我們可以通過HTTP事務(wù)來驗證


detail面板

從Deatil面板可以看出泽艘,這個事務(wù)包含了一些標(biāo)準(zhǔn)的頭部和我的位置信息欲险, 這非常糟糕,發(fā)送這些信息違反了用戶的隱私匹涮,我們可以使用這個工具生成debug 報告天试,把它存放在桌面
生成debug報告

XCtrace 工具的命令行可以以HTTP歸檔格式用來報告這個追蹤
XCtrace命令行

這是一個HTTP流量信息交換的標(biāo)準(zhǔn),就像圖片所示:har 本身是一個JSON格式的然低,所以也可以在文本編輯器中打開喜每。

結(jié)語

分享到這里就結(jié)束了,希望大家通過簡介和實例掌握HTTP Traffic的使用雳攘,能夠解決遇到的問題带兜,幫助大家的APP越來越好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末来农,一起剝皮案震驚了整個濱河市鞋真,隨后出現(xiàn)的幾起案子崇堰,更是在濱河造成了極大的恐慌沃于,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件海诲,死亡現(xiàn)場離奇詭異繁莹,居然都是意外死亡,警方通過查閱死者的電腦和手機特幔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門咨演,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蚯斯,你說我怎么就攤上這事薄风《希” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵遭赂,是天一觀的道長循诉。 經(jīng)常有香客問我,道長撇他,這世上最難降的妖魔是什么茄猫? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮困肩,結(jié)果婚禮上划纽,老公的妹妹穿的比我還像新娘。我一直安慰自己锌畸,他們只是感情好勇劣,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潭枣,像睡著了一般芭毙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卸耘,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天退敦,我揣著相機與錄音,去河邊找鬼蚣抗。 笑死侈百,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翰铡。 我是一名探鬼主播钝域,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼锭魔!你這毒婦竟也來了例证?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤迷捧,失蹤者是張志新(化名)和其女友劉穎织咧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漠秋,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡笙蒙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了庆锦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捅位。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艇搀,到底是詐尸還是另有隱情尿扯,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布焰雕,位于F島的核電站姜胖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏淀散。R本人自食惡果不足惜右莱,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望档插。 院中可真熱鬧慢蜓,春花似錦、人聲如沸郭膛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽则剃。三九已至耘柱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棍现,已是汗流浹背调煎。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留己肮,地道東北人士袄。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像谎僻,于是被迫代替她去往敵國和親娄柳。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容