iOS 平台基礎性能數據採集與實踐
引言
本文是 TalkingData 張永超老師在內部做的 KOL 分享內容總結,分享了他在 iOS 平台上進行基礎性能數據採集的實踐心得。
你也可以點擊下方語音收聽我們的分享。
大家好,這次分享的內容是關於 iOS 平台的一些基礎性能數據的採集和一些應用實踐,內容可能比較多,關於代碼的部分就不詳細講解了,謝謝。
隨著互聯網的發展,現在已經進入了移動互聯網時代,最初是橫向發展,大批量的應用程序上架,這些應用不是很注重應用的用戶體驗。近幾年來,應用程序已經向縱深發展,用戶也越來越關心用戶體驗,對開發者來說,就必須關注應用的性能所帶來的用戶流失問題。
用戶流失問題又是目前應用程序存活的關鍵問題,這樣就牽扯到整個應用的性能,數據是如何來定義、分類和收集的?
1. 什麼是性能數據?
首先看一下性能數據的定義。在計算環境中,也就是在整個操作系統中,應用程序的性能是衡量應用程序是否可用的一個指標。通俗一點說,所有可能影響應用程序實際運行情況的數據指標,都可以理解為是性能問題。再稍微延伸一點,就像我們經常聽說的 APM,也就是應用性能管理,它是一個比較新的網路管理方向,目前已經延伸到了整個應用程序的性能管理,主要針對的是企業一些關鍵業務的應用程序的監測、優化,目的是提高應用程序的可靠性和質量,保證用戶的保有量,降低 IT 的成本。
APM 是目前所有應用廠商都比較關心的一個問題,也有一些應用廠商將 APM 的一些服務作為單獨的一個組件發布,比如說國內網易的 NeteaseAPM,oneAPM,國外的 New Relic,還有聽雲、Bonree 等等,它們都是將 APM 這一個詳細的功能作為一個產品服務來推向市場,讓更多的開發者以更低的成本來加入應用程序性能的監控等等。
關於性能數據的定義做一個總結,在應用程序的運行環境中,不管是哪個平台,影響到應用程序可用性的指標,都可以認定為是一個性能數據,這是一個比較通俗的定義,也比較好理解。
以上是第一部分,相對簡單一點,對性能數據做了一個簡單的介紹。
2. 性能數據的分類
第二部分是關於性能數據的分類,這裡據不完全統計,大概有十種影響應用程序性能的問題,分別是網路連接超時、應用閃退、應用卡頓、應用崩潰、網路劫持、交互性差、CPU 使用率、內存泄露、介面不良,甚至是黑白屏。
開發者很難兼顧所有的性能問題,而且在傳統的開發流程中,我們解決性能問題主要是靠線上用戶的反饋,反饋之後開發者才能夠去分析應用性能的瓶頸在哪裡,然後修復、再發布。對用戶來說,這是一個漫長的等待過程,他勢必會把你的應用列為待卸載的狀態,也可能直接卸載了。
如何避免這種情況?解決方法是在應用的開發前期或者在線上,我們有一套完整的應用性能數據採集和監控的流程,這樣對一個應用來說,能夠達到實時監控其性能指標的目的。
對於 iOS 來說,由於 iOS 平台本身是一個相對封閉的系統,所有的東西都是蘋果公司說了算,它開放或不開放對開發者的影響比較大。簡單地說,iOS 平台下的應用性能指標,有這麼幾個分類,一個是資源的消耗情況,這裡包括 CPU、內存的消耗,流量的消耗、電量的消耗等,另一個是應用的運行情況,包括圖像、視圖的渲染情況、應用載入時間等。
這幾項可以作為 iOS 平台上面基礎性能數據的一個收集、分類,有了分類之後,我們就可以逐項採集相關數據來做分析,判斷是否影響到應用的可用性。
3. iOS 平台上的基礎性能數據採集
但是在開始之前,有三個問題要思考,第一個是為什麼要做性能數據的採集?也就是說為什麼要做性能的監控和測試,第二個問題,做完這些性能數據的採集之後,有什麼用?第三個問題就是怎麼做?
下面來逐一解答這三個問題。首先第一個問題,為什麼要在正式環境中做性能數據的採集?在很多企業裡面,App 在開發過程和上線後,都會有一些功能方面的測試與 API 的測試,並且比較成熟。但即使是這樣,不管 App 怎麼優化,架構多麼好,最終的應用是基於手機平台來運行的,不同的平台可能會給應用造成在開發和測試階段無法預知的一些問題。 這就是要做性能數據的採集和測試的原因。
第二個問題是做完有什麼用?我們先回顧一下傳統的 App 發布情況:開發人員在開發階段進行開發,開發完成之後測試人員逐個場景、逐個步驟反覆測試,但是這個過程可能會來來回回好幾遍,造成的問題就是人力、物力、包括時間都消耗在了開發-測試-開發的循環之中。
有了性能數據的實時採集,應用程序在測試階段只要保證功能完善,就可以進行線上發布,發布之後,我們有一套完整的線上性能數據採集的功能在 App 裡面,那麼對接到的後台服務就實時地拿到了應用程序在運行階段的一些性能數據,這些性能數據可能對應的場景步驟都不相同,通過對這些性能數據的分析,我們可以對應用程序進行資源優化,然後再進行發布,省去了從用戶的反饋,到測試人員和開發人員再不斷調優測試的循環。
第三個問題是怎麼去做?蘋果公司的開發者工具 Xcode,已經提供了一套工具,叫 Instruments,是集成 Xcode 裡面的一個組件,用這個工具,可以把這些數據在開發階段進行測試和調優,但是開發階段的測試和調優並不等同於線上環境的實際情況,因為用戶不同,平台不同,手機的硬體也不同,所以線上環境的監控會更加重要一些。
第三部分內容是這些性能數據到底在 iOS 平台是如何去採集?以及蘋果公司是不是對這些性能數據的採集提供了友好的 API 等。
第一個是 CPU,中文叫中央處理器,英文叫 Central Processing Unit,是整個計算機的主要設備之一,主要功能是解釋計算機的指令以及處理計算機軟體中的數據。
對於 iOS 平台來說,它是最重要的計算資源之一。比較糟糕的應用程序可能會造成整個 CPU 持續高負載運行。對用戶來說,一方面最直接的影響就是造成應用卡頓,另一方面是手機發燙,電量會快速消耗,嚴重影響到用戶體驗。一個合理的應用程序,它的 CPU 可能會在某一瞬間有高的增長,但是增長完成之後它會趨於平穩。要知道一個 App 的 CPU 佔用率,在 iOS 平台需要了解的知識挺多的。
第一個就是線程,線程是調度和分配的基本單元,在作為應用程序的進程運行時,它包含了多個不同的線程,這一點也是和安卓平台不同的,安卓平台是允許多個進程同時存在的,iOS 平台一個應用程序是一個進程,一個進程裡面有多個線程,也就是說一個應用程序相當於含有多個線程的進程。
另外 iOS 平台是基於 Apple Darwin 內核,由 kernel、XNU 和 runtime 三部分組成的,而 XNU 是 Darwin 的內核,它的意思就是「X is not UNIX」的縮寫,是一個混合內核,但是這個混合內核是由 Mach 微內核和 BSD 組成的。那麼 Mach 內核的話是一個輕量級的一個操作系統平台,它只能完成一個操作系統最基本的職責,比如剛才說到的進程、線程、虛擬內存、管理,還有任務的調度,進程之間的通信,消息的傳遞等等。其他像文件的操作,設備的訪問等都是由 BSD 層來實現的。
進程子系統的架構圖
而上面這張圖是 iOS 平台和 macOS 中進程子系統的一個架構圖,它倆之間的相同點就是整個線程技術都是基於 Mach 線程技術實現的,在 Mach 層中有一個結構體, 叫做 thread_basic_info,它這個結構體中提供了線程的基本的信息。
thread_basic_info
上面提到了那個 Mach task 可以看作是一個機器無關的線程執行環境。一個它所包含了它的整個線程列表,在 iOS 內核中提供了一個 task_threads 的 API 調用,用來獲取整個 task 的線程列表,然後就可以通過 thread_info 來查詢整這個線程的一些信息,它整個結構體是下面這樣子的。
task_threads 結構體
有了這個結構體之後,可以得到整個線程列表,這樣每一個線程所佔用的 CPU 就可以計算出來,最終可以得到 App 的 CPU 佔用情況。我們不僅可以拿到這個 App 的 CPU 佔用情況,也可以拿到 CPU 的一些其它信息,比如 CPU 的頻率,包括最大頻率和最小頻率,這些數據也是能夠體現出來一個 App 的 CPU 使用情況的。
下面看一下另一個比較重要的性能數據指標,就是內存的使用情況,這類內存主要是物理內存,物理內存與 CPU 一樣是系統中比較稀少的資源,也是最容易發生資源競爭的一個單元,與應用的整個性能也是直接相關的。在 iOS 平台上通常的官方做法是犧牲別的應用來保證當前應用的內存使用,當應用處於後台時,它會自動監控這個應用所需內存的情況,在達到一定時間之後,它會把這個應用所需的內存全部 Kill 掉,然後把這些內存讓給當前應用來使用。
那麼內存是如何獲取的?蘋果也提供了對應的一個結構體,這個結構體是 mach_task_basic_info,在這個 mach_task_basic_info 結構體中會給出幾個內存的大小,包括虛擬內存、物理內存等等一些其他的信息,通過結構體可以拿到系統中 App 在運行時的一些內存使用情況,整個結構體如下。
mach_task_basic_info 結構體
接下來介紹應用的啟動時間的衡量指標,應用的啟動在 iOS 平台來說它分為兩種方式,一種是冷啟動,一種是熱啟動,冷啟動就是應用完全沒有運行過,當用戶點擊應用的 icon,然後應用才載入到最終呈現的界面,這是冷啟動方式。
熱啟動是當應用在前台時,按了 home 鍵將應用置於後台,再從後台喚醒應用到前台的過程,這叫熱啟動。這是兩種不同的啟動方式,在 iOS 平台上運行的方法也不同,通常情況下是在這兩種方法中加入一定的計時,來衡量、記錄與採集該應用的啟動時間。
應用啟動時序圖
上面這張圖就是蘋果官方給出的一個應用啟動的時序圖,從這個圖中可以看到兩種方式,一種是 Launch Time 部分,也就是綠色部分,是冷啟動方式,下面 Running 部分是熱啟動過程,右邊 Your Code 這部分是應用程序中的一些代碼,熱啟動和冷啟動對應的應用中所調用的方法或者說所響應的方法是不同的,所以我們可以在不同的方法中加入計時來衡量最終整個應用程序的啟動時間。
計算運行時間
上面這張圖是整個 App 運行時間是如何計算的,這裡大家主要看一下,main 函數之前和 main 函數之後,這兩部分對照上面這個圖應該可以大體明白 iOS 平台冷啟動、熱啟動以及總的應用啟動時間的計算方式了。
下面是最後一個分享的採集點,就是渲染的效果,渲染效果主要收集的是 FPS,也就是每秒的幀數,FPS 是測量用於保存顯示動態視頻的信息數量,每秒鐘幀數越多顯示的動作就會越流暢,一般情況下都是保持在 50 和 60,這樣的話用戶用起來比較流暢。
在 iOS 平台上沒有直接獲取 FPS 的 API,但是在 Xcode 提供的工具中能夠監測到 FPS,為了能夠在線上環境中使用,我們這裡採用了另外一種方式,就是監測應用視圖刷幀頻率,也就是刷新界面的次數。
FPS 過低的情況下出現的直接問題就是卡頓,卡頓對用戶來說可能是最不能忍受的一個現象。所以在開發階段,如果開發者能夠實時監控整個視圖的 FPS 情況,對應用的優化、FPS 的調優都是很好的一個參考數據。
對 FPS 的收集牽扯到 iOS 平台一些底層的內容,如它的 RunLoop,RunLoop 是 iOS 平台底層的運行循環,這裡不再過多細講,只能說 iOS 平台上能夠收集到的 FPS 不是真實的 FPS,只能作為開發者和測試的一個參考指標。
這一部分內容相對比較多,也比較雜,所以暫時先講到這裡。具體的代碼,包括裡面一些函數的說明,感興趣的話可以參考 Apple 性能指南,其中涵蓋了多種性能相關的說明文檔。
4. 性能數據的用途
接下來看一下性能數據的用途,性能數據我們採集上來之後到底有什麼用途?有一個關鍵的點就是 iOS 平台下應用程序發布之後都有哪些痛點?如果找到這些痛點,我們就能知道應用性能數據的意義和用途在哪裡。
首先 iOS 平台的應用必須在 App Store 中下載,這是蘋果自家掌控的一個平台,用來做應用程序的發布和一些其他業務。發布之後,開發者如果遇到了一些應用程序上面的問題,或者用戶看到應用程序的上的問題,必須由開發者根據這些問題去找問題所在的原因、修復,然後再發布到 App Store 中。
App Store 有一個比較頭疼的問題就是審核周期,雖然現在蘋果已經加快了審核周期,但是這個審核周期可能仍然無法滿足 App 遇到一些嚴重問題的修復和發布進度。
因此如果 iOS 的開發者能夠在應用發布之後,實時監控應用程序的一些性能問題、穩定性問題、電量問題、兼容性問題等等,就可以在用戶可能還沒有發現的前提下把應用程序修復,提交 App Store。這樣就省去了用戶發現問題、報給開發者、開發者修復之後再提交 App Store,App Store 審核周期又很長,導致了用戶可能無法忍受而直接卸載 app。
簡單總結一下性能數據的用途,它最大的意義就在於開發者能夠快速地發現問題,修復問題。
5. 性能數據採集的未來
最後一個問題是性能數據採集的未來,在整個應用數據採集的過程中,很多人覺得移動應用平台或者說 App 裡面能夠採集的數據已經沒有了,只能是目前的狀況。其實不一定,只能說看似比較明顯的數據,我們已經採集了,但是一些深層次的數據可能還沒有被發現,或者說可能我們認為它還不重要,所以說應用數據的採集在後期的話可能會是一個比較漫長的過程。
6. Q&A
Q1:蘋果是否有性能數據的工具?
A1:蘋果的開發者工具 Xcode 內置的一個 Instruments 的應用性能數據監測工具。但是這些工具開發者只能在開發和測試的時候用,並不能夠在線上的環境中使用,因此這塊我們會做一些線上環境數據的採集,來幫助開發者在線上環境中對應用的性能進行分析,優化等等。
Q2:我們的 SDK 集成到客戶的 app 中是一個線程的方式被客戶 app 調用的嗎?我們的 SDK 在客戶 app 中運行的整個生命周期中只有一個線程嗎?
A2:我們的 SDK 並不是在客戶的應用程序中以單一的線程執行,因為蘋果允許用戶自己去創建某段代碼或者某個功能所運行的線程,所以說我們的 SDK 會有多個線程,那麼多個線程是在適當的時機去創建,然後使用完成之後去銷毀,以避免應用的 CPU、內存這些性能數據的異常等等。
Q3:我們的 SDK 對客戶 app 會造成影響嗎?
A3:我們的 SDK 對於用戶 app 的影響,第一是 app 的大小會增大,增大的幅度大小取決於客戶 app 開發者打包時的 Xcode 設置。
第二個影響,就是最終客戶 app 的使用者,流量會略有增加,但是我們的 SDK 已經對所需要發送的數據進行了最小化的壓縮,甚至對帶寬的使用也進行了一些優化,這樣使它的流量消耗非常非常低,可以說是忽略不計。目前,我們在正在進一步的優化 SDK,為了最小化各種影響,我們一直在努力。
題圖來自:akket.com
※獨具匠心的訴求表達,很贊!
※此情綿綿無盡時 筆尖殘留的微溫,淡化了離愁
TAG:全球大搜羅 |