日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

不止性能优化,移动端 APM 产品研发技能

發(fā)布時(shí)間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 不止性能优化,移动端 APM 产品研发技能 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

江賽,聽云研發(fā)總監(jiān),負(fù)責(zé)聽云移動(dòng)端產(chǎn)品的研發(fā)工作。在 OSC 第 55 期廣州源創(chuàng)會(huì)上發(fā)表了題為《移動(dòng)端 APM 產(chǎn)品研發(fā)技能》的演講。現(xiàn)場(chǎng)介紹移動(dòng)端 APM 產(chǎn)品底層技術(shù)細(xì)節(jié)與實(shí)現(xiàn)方法, 演示如何通過在代碼中埋點(diǎn)來解決移動(dòng) APP 的性能問題 ;分享在實(shí)際產(chǎn)品開發(fā)中碰到的問題和一些經(jīng)驗(yàn),以及一些技術(shù)細(xì)節(jié)。

一、移動(dòng) APM 概況

移動(dòng)端 APM 產(chǎn)品,從字面上來理解,APM(application performance monitor)就是應(yīng)用性能相關(guān)的監(jiān)測(cè),可隨著現(xiàn)在產(chǎn)品的邊界越來越模糊,監(jiān)測(cè)的范圍不僅包括 performance,還包括用戶行為,以及在穩(wěn)定性、卡頓、崩潰這些方面的數(shù)據(jù)都有監(jiān)測(cè),已經(jīng)遠(yuǎn)遠(yuǎn)超過 performance 這一個(gè)角度,畢竟產(chǎn)品結(jié)構(gòu)越來越大了。

所以對(duì)于這樣一個(gè)產(chǎn)品,要做數(shù)據(jù)監(jiān)控和數(shù)據(jù)分析,它的基本前提是什么呢?就是必須要采集大齡的數(shù)據(jù),包括一些基本的數(shù)據(jù)。將這些數(shù)據(jù)放在不同的維度分析。

舉個(gè)例子,從網(wǎng)絡(luò)的角度來說,有用戶反饋某個(gè)產(chǎn)品在某個(gè)運(yùn)營(yíng)商范圍接入的情況下,網(wǎng)絡(luò)性能很差。這個(gè)數(shù)據(jù)就會(huì)直接從報(bào)表里面去體現(xiàn),因?yàn)闀?huì)采集到一些基本的網(wǎng)絡(luò)數(shù)據(jù),也會(huì)采集到其他的不同的維護(hù)數(shù)據(jù),然后這些問題就會(huì)展現(xiàn)出來。

從這張圖來看,數(shù)據(jù)是我們產(chǎn)品的一個(gè)移動(dòng)研究方向,而且我們的產(chǎn)品會(huì)支持蘋果、Android 還有 Web 這三端。會(huì)采集的數(shù)據(jù)包括:網(wǎng)絡(luò)數(shù)據(jù)、交互行為數(shù)據(jù)、穩(wěn)定性相關(guān)數(shù)據(jù)和一些其他的數(shù)據(jù)(例如采集手機(jī)的信號(hào)。這些數(shù)據(jù)會(huì)有一些不同的應(yīng)用,比如說運(yùn)營(yíng)商,它在部署各種基站的時(shí)候,會(huì)有一個(gè)參考值,就是哪個(gè)地方信號(hào)不太好,它會(huì)在那里部署基站,但是怎樣知道信號(hào)不好呢?不可能在每一個(gè)角落都放一臺(tái)手機(jī)看信號(hào)如何。此時(shí)我們的產(chǎn)品就可以完成這個(gè)任務(wù),移動(dòng)端可以采集到這些信號(hào),然后根據(jù)不同的地域來分析手機(jī)信號(hào)分布情況),這就是采集數(shù)據(jù)的大概內(nèi)容。

然后往下細(xì)分會(huì)有更多類別。例如網(wǎng)絡(luò)數(shù)據(jù),從應(yīng)用層的數(shù)據(jù)來看,主要是采集 HTTP/HTTPS 的數(shù)據(jù),但又不僅僅是 HTTP/HTTPS 數(shù)據(jù),比如說一條 HTTP 請(qǐng)求,假如從 Web 上或者是瀏覽器中輸入一個(gè)網(wǎng)址,我們會(huì)把所有的 HTTP 請(qǐng)求內(nèi)容分析出來,例如出去包的長(zhǎng)度、回來包的長(zhǎng)度和 response 的時(shí)間等等。如果出現(xiàn)錯(cuò)誤的時(shí)候,還會(huì)把 response 的包和頭部信息打印出來,會(huì)把 HTTP 協(xié)議請(qǐng)求全部分析一遍,分析字節(jié)大小,響應(yīng)時(shí)間,還有錯(cuò)誤這些情況。然后還會(huì)往下分析,比如 HTTP 請(qǐng)求訪問之前需要做 TCP 鏈接的所用時(shí)間。

這些數(shù)據(jù)正常情況下是沒有辦法采集的,需要特定的技術(shù),這個(gè)也是今天我要分享的內(nèi)容 —— 我們是如何抓取這些底層數(shù)據(jù)的。

還有一個(gè)是頁(yè)面加載的數(shù)據(jù),頁(yè)面的加載包含三種數(shù)據(jù)(頁(yè)面加載、瀏覽器渲染和 DOM 加載)。Android 和 iOS 會(huì)通過 JS 注入監(jiān)控一些數(shù)據(jù),和監(jiān)測(cè)一些頁(yè)面加載的詳細(xì)數(shù)據(jù)。

關(guān)于交互行為數(shù)據(jù),舉個(gè)例子,產(chǎn)品會(huì)監(jiān)控用戶在一個(gè)應(yīng)用里的一些點(diǎn)擊行為,像一系列的滑動(dòng),對(duì)菜單的選中。比如說點(diǎn)擊一個(gè)按鈕以后,如果它的響應(yīng)時(shí)間過長(zhǎng),一般閾值是 3 秒鐘,如果點(diǎn)擊完按鈕 3 秒后才處理完,我們會(huì)自動(dòng)把事件抓取并上報(bào)。現(xiàn)在我們還可以做到,當(dāng)監(jiān)測(cè)到卡頓以后,會(huì)自動(dòng)去把當(dāng)前的操作截屏(可以做一秒鐘 10 幀的截屏)。通過一秒鐘 10 幀的數(shù)據(jù)而生成的動(dòng)畫,也就能看到卡頓的時(shí)候所在的頁(yè)面。這個(gè)產(chǎn)品暫時(shí)還沒發(fā)布,但技術(shù)上已經(jīng)實(shí)現(xiàn)了。現(xiàn)在關(guān)鍵的問題是普通的截屏?xí)浅S绊懶阅芎秃碾?#xff0c;現(xiàn)在能做到 1 幀數(shù)據(jù)在 5 毫秒左右,效率非常高,截屏速度也非常快。

關(guān)于穩(wěn)定性,穩(wěn)定性就是崩潰和 ANR(卡頓)相關(guān)的。有一些開源項(xiàng)目可以支持這種需求,所以類似崩潰、ANR 這些數(shù)據(jù)的采集難度不大。

收集了不同的源數(shù)據(jù)以后,就會(huì)接觸到不同的維度,這些維度包括地域、運(yùn)營(yíng)商、接入方式、設(shè)備、操作系統(tǒng)、應(yīng)用版本以及其他一些維度數(shù)據(jù)。根據(jù)這些維度數(shù)據(jù)和一些自定義的相關(guān)信息,會(huì)做特定的網(wǎng)絡(luò)數(shù)據(jù)監(jiān)控。通過這個(gè),就可以看到對(duì)應(yīng)的不同源數(shù)據(jù)在不同的維度組合下的結(jié)果,比如可以選擇某一個(gè)地方、某一個(gè)運(yùn)營(yíng)商或者某個(gè)設(shè)備在某種接入方式上,它的 HTTP 請(qǐng)求效率,這就是基本源數(shù)據(jù)以及基本數(shù)據(jù)的應(yīng)用。

很多應(yīng)用廠商也嘗試自己抓取這些龐大的數(shù)據(jù),但如果用傳統(tǒng)的方式來做,就意味著需要打很多的點(diǎn),比如說一段代碼,需要在 excute 進(jìn)入的地方打一個(gè)點(diǎn),出去的地方也打一個(gè)點(diǎn),同時(shí)還要把參數(shù)抓取下來做參數(shù)的解析,這就意味著如果手工來做這種工作,工作量會(huì)非常大,因?yàn)樗斜O(jiān)控的地方都要埋點(diǎn),而且一旦這段代碼發(fā)生變化,也就要重新去修改埋點(diǎn)的代碼,而且重新去埋點(diǎn),也會(huì)導(dǎo)致工作量非常大。

因此做數(shù)據(jù)采集的時(shí)候,我們有一個(gè)基本原則:盡量不讓程序員做任何事情。添加一行初始化代碼就夠了。那么如何采集到這些數(shù)據(jù)?這就是數(shù)據(jù)采集的基礎(chǔ),自動(dòng)埋點(diǎn)技術(shù)。這些埋點(diǎn)的操作不需要自己做,會(huì)通過程序自動(dòng)完成。下面介紹幾種自動(dòng)埋點(diǎn)的方法。

二、APM 實(shí)現(xiàn) —— 自動(dòng)埋點(diǎn)技術(shù)的介紹

主要通過以下的技術(shù)手段實(shí)現(xiàn):

下面對(duì)每一個(gè)技術(shù)細(xì)節(jié)展開進(jìn)行講述:

對(duì)于 ByteCode 的處理,支持 Java ByteCode 的注入以及 Dalvik ByteCode 的注入。在內(nèi)應(yīng)用層會(huì)提供 Hook 方法來 Hook 分析 C/C++ 代碼,JavaScript 相關(guān)的會(huì)通過 JS 注入的方式來采集數(shù)據(jù)。

看起來比較抽象,下面一一展開來描述:

1. 從 Java 源代碼到 Dalvik Bytecode

對(duì)于 Android 程序員來說,大部分代碼都是用 Java 寫的,拓展名是 .java 的文件。但真正打包編譯完以后,會(huì)生成 apk 文件。如果你把它解壓會(huì)看到有一個(gè) dex 文件,因?yàn)楝F(xiàn)在的包越來越大了,可能會(huì)有多個(gè) dex 文件,那么這些 .java 文件是怎么變成 dex 文件的,這個(gè)過程是如何的?

編譯的過程是首先從 .java 文件到 class 文件,然后 class 文件再到 dex 文件。.java 文件到 class 文件是通過 javac 編譯,然后再通過 Android SDK 下的一個(gè)工具 dx 將 class 文件編譯成 dex 文件。

在 Android 的虛擬機(jī)里面,正常情況下編譯完以后,Java 虛擬機(jī)里面執(zhí)行的是 .class 文件(即 Java Bytecode),但是在 Android 的 Dalvik 虛擬機(jī)或者 ART 里,不能直接執(zhí)行 Java Bytecode,因此需要將 Java Bytecode 做一次轉(zhuǎn)換,轉(zhuǎn)成 Dalvik Bytecode。該過程就是使用 dx 這個(gè)工具轉(zhuǎn)換的,而且是在編譯的時(shí)候完成。其實(shí)就是不同的格式表述,.class 文件只是用了另外一種字節(jié)碼的格式來表述。這個(gè)東西看似很簡(jiǎn)單,但如果了解編譯的過程,就可以做很多的事情。 class 文件生成了以后,還沒有轉(zhuǎn)成 dex 文件這一步,就可以通過 ASM 技術(shù),對(duì) Java Bytecode 進(jìn)行改寫,從而插入要監(jiān)控的代碼。

下面通過一個(gè)實(shí)際的例子來講述。

先來看代碼:

Example Java source: Foo.java class Foo {public static void main(String[] args) {System.out.println("Hello, world");?}?public int method(int i1, int i2) {int i3 = i1 * i2;return i3 * 2;} }

這段代碼的功能很簡(jiǎn)單,里面有一個(gè)方法,傳進(jìn)來兩個(gè)參數(shù),先將這兩個(gè)參數(shù)相乘,再把結(jié)果除以 2 返回。通過 javac 把它編譯成 Java Bytecode,然后用 javap?可以看到?Java Bytecode 的指令。這是一個(gè)很簡(jiǎn)單的 Java Bytecode 指令,取得兩個(gè)參數(shù),然后做乘積。imul 指令就是 Java Bytecode 的一個(gè)基本指令,之后就是把兩個(gè)參數(shù)壓棧,imul 指令會(huì) pop 出棧底的兩個(gè)數(shù)。

$ javac Foo.java $ javap -v Foopublic int method(int, int);flags: ACC_PUBLICCode:stack=2, locals=4, args_size=30: iload_11: iload_22: imul3: istore_34: iload_35: iconst_26: imul7: ireturnLineNumberTable:line 6: 0line 7: 4

可以看到,方法的名字和參數(shù)都沒變。其實(shí) Java Bytecode 和 Dalvik Bytecode 很大的一個(gè)區(qū)別就在這里,Java Bytecode 需要借助堆棧來模擬這種操作(乘法、除法),通過棧來臨時(shí)存放這些變量,但在 Dalvik Bytecode 里就不是通過棧來實(shí)現(xiàn),而是通過寄存器實(shí)現(xiàn)。看一個(gè)棧的操作示例:

Stack Before?? ?After?? ? value1?? ?result?? ? value2?? ?...?? ? ...?? ?...?? ?(imul指令對(duì)棧的操作)

先是傳入兩個(gè)變量 value1 和 value2,imul 執(zhí)行完以后就把結(jié)果加到棧里邊,這就是一個(gè)典型的棧操作。

因?yàn)?Java Bytecode 沒有辦法在安卓手機(jī)上運(yùn)行,因此需要將 Java Bytecode 繼續(xù)通過 dx 工具把它編譯成 Dalvik Bytecode。很多時(shí)候大家都是通過編譯工具進(jìn)行編譯,沒有嘗試通過手工進(jìn)行編譯,建議可以嘗試一下。通過 dx 就可以把 class 文件編譯成一個(gè) dex 文件,然后通過 dexdump 命令,把 dex 文件 dump 出來。可以看到,剛才的 Java Bytecode 里幾行乘法指令,在這就就變成了一行指令。

可以看到,首先指令長(zhǎng)度變小了,第二 Dalvike Bytecode 引入了寄存器的概念。而 Java Bytecode 的函數(shù)調(diào)用全部是通過棧來模擬的。這種方式對(duì)代碼性能,以及代碼結(jié)構(gòu)大小有影響,而且寄存器本身的性能要比棧高很多。

再看一下,剛剛那三行代碼兩次 pop 操作,一次乘積,一次 push 操作,現(xiàn)在變成這樣一個(gè)操作。就是這個(gè)指令,經(jīng)過目標(biāo)計(jì)算器,源計(jì)算器,操作完以后,存在源計(jì)算機(jī),現(xiàn)在變成這種形式。

下面來看一下 Java Bytecode 與 Dalvik Bytecode 的對(duì)比:

Java Bytecode 和 Dalvik Bytecode 有什么區(qū)別?前者用的是棧,后者用的是寄存器。

這些對(duì)于自動(dòng)插碼技術(shù)有什么作用?前面提到的指令級(jí)插碼又有什么作用?其實(shí)這些是基本工作,首先要對(duì)Java Bytecode 非常的熟悉,之后要了解整個(gè)編譯過程。

這個(gè)代碼就是通過動(dòng)作分析 Java Bytecode 注入的,反編譯出來就是這樣。我們需要分析一些關(guān)鍵的方法,還有特定方法,找到函數(shù)的頭和尾,插入需要的代碼,第一步為獲取開始時(shí)間;第二,獲取完成的時(shí)間,之后進(jìn)行上報(bào)。像做一些錯(cuò)誤處理,會(huì)對(duì)異常進(jìn)行捕捉,這樣就可以自動(dòng)分析你的 Bytecode 來做注入。

還有一個(gè)特殊的情況,就是需要監(jiān)控的是這個(gè)調(diào)用,或者說監(jiān)控這個(gè)調(diào)用的反饋值,這些情況都會(huì)出現(xiàn)。但所有的變化都是基于對(duì) Bytecode 上下文的理解,然后插入對(duì)應(yīng)的指令。這個(gè)技術(shù)不是我們獨(dú)創(chuàng)的,ASM 技術(shù)已經(jīng)有很多年了,各位可以去看一些開源的 ASM 項(xiàng)目。

還有一個(gè)技術(shù),Java Bytecode 注入是我們產(chǎn)品現(xiàn)在主要的注入方法,但是也還有很多其他注入的方法,下面要講的就是另外一種的方式 ——?通過 .smali 注入,具體的邏輯如下圖所示:

通過一些 smali 反編譯工具,轉(zhuǎn)成 smali 文件,靜態(tài)分析這些文件,分析完以后會(huì)做代碼的注入,然后重新打包,再加一個(gè)簽名就可以了。smali 不是 Android 官方的 Bytecode,是一個(gè)開源的 Bytecode。

這些大家都不陌生,做 APP 開發(fā)很多時(shí)候會(huì)用這些工具幫助分析一些事情。同樣你也可以借鑒一些新的思路,通過這種方式分析 APK。認(rèn)為存在惡意行為就分析。另外還可以做動(dòng)態(tài)調(diào)試,把一些參數(shù)打印出來。

比如說寫了一個(gè)工程,可以做一個(gè)定制,寫一個(gè)簡(jiǎn)單的SDK。分析一個(gè) APP 的時(shí)候,需要分析其網(wǎng)絡(luò)行為,就把 SDK 注入進(jìn)去,然后打包,之后看網(wǎng)絡(luò)訪問過程當(dāng)中訪問的什么主機(jī)、IP。如果有加密,那就通過另外一個(gè)話題對(duì)流做解密,一般的情況下,傳輸?shù)臄?shù)據(jù)都可以看到。

2. APM 實(shí)現(xiàn) ——?native inline hook

因?yàn)?Android 中很多代碼不一定是用 Java 寫的,也可以用 C/C++ 寫。這種代碼不能通過 Bytecode 的方式來注入。看下面這張圖

這是一個(gè)普通的調(diào)用關(guān)系,調(diào)用者調(diào)用被調(diào)用者執(zhí)行,執(zhí)行完以后返回。這是正常的處理流程。但如果要監(jiān)測(cè)這個(gè)被調(diào)用的方法,想要拿到參數(shù),以及這個(gè)方法執(zhí)行多長(zhǎng)時(shí)間,還想知道這個(gè)返回值,如何實(shí)現(xiàn)?邏輯上很簡(jiǎn)單,把被調(diào)用方法頭幾行指令做修改。把指令改成 JMP 指令,JMP 到這個(gè)監(jiān)控方法里面,通過 hook 的方式做跳轉(zhuǎn)。這里做參數(shù)、相關(guān)函數(shù)的記錄,做完以后再重新按照這個(gè)軌跡返回。

如何做到這一步呢?首先,把頭幾行做跳轉(zhuǎn)。這需要對(duì) ARM 指令,對(duì)各種架構(gòu)比較熟悉才能做到。大部分程序員都學(xué)過匯編指令,但遇到的時(shí)候覺得很復(fù)雜。實(shí)際上并不復(fù)雜,只是接觸的少,其實(shí) ARM 32 指令不多。根據(jù)后面 3 位,4 位可以做區(qū)分。還有一些分值指令,數(shù)學(xué)預(yù)算指令。那么,分析這些指令的時(shí)候,首先對(duì)于指令架構(gòu)要很熟悉,而且,要知道源計(jì)算機(jī),目標(biāo)計(jì)算器在哪里。比如說,最終跳轉(zhuǎn)指令的時(shí)候,要知道跳轉(zhuǎn)怎么計(jì)算,24 位 offset 怎么跳轉(zhuǎn),24 位怎么轉(zhuǎn)換為絕對(duì)地址。如果把基本概念弄明白,不要求會(huì)寫,就可以做下面的事情了。

先看一下剛剛說的方法怎么做到的。

需要改寫這個(gè)方法的頭兩行指令,頭兩行指令替換成這樣的指令。PC 指令就是當(dāng)前運(yùn)行時(shí)的邏輯地址,PC 寄存器。因?yàn)?ARM 32 會(huì)做一個(gè)預(yù)加載,這個(gè)會(huì)指向下兩行指令。如果將 PC 指令減 4,就是變?yōu)?PC 加 4,這個(gè)操作是把下一行指令移到 PC 寄存器中。如果改寫 PC 寄存器就實(shí)現(xiàn)了跳轉(zhuǎn),雖然只有兩行代碼,但是可以想到這其實(shí)要花很長(zhǎng)的時(shí)間。

這需要了解 ARM 指令,知道這個(gè) ARM 指令執(zhí)行的過程,還要知道通過修改 PC 指令實(shí)現(xiàn)跳轉(zhuǎn)。通過改寫頭兩行指令,就可以把它跳轉(zhuǎn)到任何地址。而且這個(gè)地址就是 4 字節(jié),32 位,4G 空間。可以跳轉(zhuǎn)到任何函數(shù),但這還沒結(jié)束。后兩行做了以后,要把頭兩行移到另外一個(gè)地方。但是,移動(dòng)指令的時(shí)候因?yàn)橐恍┲噶畋旧砭褪且蕾?PC 指令,所以要去做指令的修復(fù)。因此更多的工作其實(shí)就是在修復(fù)這些被移走的指令。下面的例子是一個(gè) B 指令修改,是寫實(shí)際代碼的一部分。

來看一下這一行代碼是什么意思。123,2 個(gè) 0 是 8 位,8123,高位是 0,0,F。如果是 31 到 32 位,我們現(xiàn)在取的值是實(shí)際上就是取這 4 位,1234,取 4 位的值,通過這一行指令取這個(gè)值。然后通過 4 個(gè)值區(qū)分這些指令類型。取出來了以后,如果這個(gè)是 A,可以看一下 B 指令的方式,1010,這個(gè)是 1010,一個(gè)是1,就是 BR 指令,跳出去再跳回來。如果無條件這里就是 0,1010 正好是多少就是 10,就是 A,如果是 B指令。B 指令跳轉(zhuǎn)依賴寄存器,首先算出來這個(gè)地址,把絕對(duì)地址存在這里,頭一行指令在這里。

如果要真正把這個(gè)弄明白,可以通過編寫 C 代碼做到。如果做到這樣覺得很有成就感,把系統(tǒng)的 malloc,或者是 new 給 ?hook 住,可以監(jiān)測(cè)所有的 native 內(nèi)存申請(qǐng)和釋放。

將 hook 技術(shù)應(yīng)用在產(chǎn)品上面,發(fā)現(xiàn)很多的產(chǎn)品都是依賴這個(gè)技術(shù)的。比如安全方面,很多產(chǎn)品也是通過這種方式做的。還有通過這種方式來做一些底層資源修改和調(diào)度,這個(gè)可以用在很多的方面。因?yàn)榧夹g(shù)是為了產(chǎn)品服務(wù)的,只要把技術(shù)弄明白就可以了,最終還是會(huì)產(chǎn)品化。這是像我這種做很多年技術(shù)的人切身的體會(huì)。有時(shí)候也是會(huì)沉迷在技術(shù)里面,總覺得做一些產(chǎn)品的工作就是浪費(fèi)時(shí)間。現(xiàn)在想想,并不如此。

最后一點(diǎn),前面講的這些,都是一些自動(dòng)嵌碼技術(shù),包括 Java 應(yīng)用,還有 C++ 應(yīng)用。數(shù)據(jù)都是自動(dòng)采集的。在編譯時(shí)插碼,在運(yùn)行時(shí)使用 hook,這些都可以做,因?yàn)楫a(chǎn)品已經(jīng)很成熟。聽云現(xiàn)在運(yùn)行著?5 億終端,有一些大的電商類也已經(jīng)在用聽云的 SDK。

舉個(gè)例子,想通過聽云對(duì) TCP 層的監(jiān)測(cè)結(jié)果來觀察負(fù)載均衡調(diào)度情況,同一個(gè)主機(jī)有一堆 IP,正常情況下是沒有辦法拿到這個(gè)結(jié)果的。我們不僅可以拿到 DNS 時(shí)間,還可以拿到 DNS 結(jié)果,真實(shí) IP 是什么,通過這些情況可以看到負(fù)載均衡服務(wù)器,即調(diào)度出來的結(jié)果情況以及 IP 分布情況,另外還有 TCP 三次握手時(shí)間,SSL 握手時(shí)間等。

這些數(shù)據(jù)都非常的有用。安卓程序員經(jīng)常糾結(jié)使用哪些網(wǎng)絡(luò)庫(kù),是 urlconnection,還是 okhttp。分別都有什么優(yōu)缺點(diǎn)。這個(gè)我們就給你們做了一個(gè)強(qiáng)大的技術(shù)驗(yàn)證。

第一個(gè)問題,比如說,在程序里面連著發(fā)了 10 個(gè) request。現(xiàn)在 HTTP 訪問的傳輸層都是基于 TCP,但每發(fā)一次 request 都要做一次 TCP 連接嗎?仔細(xì)想想,對(duì)于同一個(gè)地址肯定沒有必要,這樣做就是浪費(fèi)時(shí)間。然后遇到的就是 TCP 復(fù)用技術(shù),通過這種技術(shù),就可以監(jiān)測(cè)對(duì)于一個(gè)同一個(gè)目標(biāo)地址發(fā)生多少次?TCP?connect 操作,這就知道在這個(gè)訪問時(shí)間內(nèi)有沒有復(fù)用之前的連接。所以,就可以得出一個(gè)指標(biāo)數(shù)據(jù),即發(fā)生了多少次 TCP 連接。

下圖是 APM 產(chǎn)品

通過這種技術(shù)可以監(jiān)測(cè)一些關(guān)鍵指標(biāo)數(shù)據(jù),因?yàn)椴扇〉讓釉瓟?shù)據(jù),很多點(diǎn)就會(huì)把這個(gè)原數(shù)據(jù)還原出應(yīng)用場(chǎng)景,客戶想出來的場(chǎng)景比我們多。這些原數(shù)據(jù)都是最寶貴的數(shù)據(jù),并且最關(guān)鍵的是不需要你再去做額外的工作,也是 APM 的價(jià)值所在。

三、總結(jié)

今天講的內(nèi)容比較抽象,講的是研發(fā)過程中的一些經(jīng)驗(yàn),技巧和總結(jié)。這個(gè)技術(shù)可能對(duì)各位現(xiàn)在的工作不會(huì)有直接的幫助,因?yàn)樘讓?#xff0c;但也希望可以給各位對(duì)自己工作的方式帶去一定的思考。無論怎樣,還是需要把底層的知識(shí)弄明白,畢竟這對(duì)于寫代碼有幫助。

轉(zhuǎn)載于:https://my.oschina.net/osccreate/blog/795760

總結(jié)

以上是生活随笔為你收集整理的不止性能优化,移动端 APM 产品研发技能的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。