<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    有贊移動(dòng)性能監(jiān)控平臺(tái)(一)

    共 6778字,需瀏覽 14分鐘

     ·

    2021-02-25 21:25

    前言

    隨著移動(dòng)端業(yè)務(wù)復(fù)雜度的提升,開發(fā)同學(xué)在編寫業(yè)務(wù)的時(shí)候往往容易忽略性能問題,雖然有贊移動(dòng)端自研了 APM ,但是 APM 采集的都是線上的數(shù)據(jù),無法在 QA 與開發(fā)階段提前發(fā)現(xiàn)問題,為了保障軟件的穩(wěn)定性,需要補(bǔ)齊線下監(jiān)控能力,避免性能問題上線對(duì)商家經(jīng)營過程造成影響。

    一、架構(gòu)設(shè)計(jì)

    整體基于 APM 現(xiàn)有框架迭代線下監(jiān)控能力,并在端上開發(fā) AWACS 可視化工具,通過全局懸浮窗,并結(jié)合提醒能力(彈窗與 Toast 提示)實(shí)時(shí)通知測(cè)試人員進(jìn)行問題查看,同時(shí)后臺(tái)也會(huì)定時(shí)分析測(cè)試環(huán)境采集的性能數(shù)據(jù),進(jìn)行管理與分配。

    QA 同學(xué)基于 Appium 補(bǔ)齊了 UI 主流程 case ,通過自動(dòng)化測(cè)試最大程度確保每次應(yīng)用發(fā)版的穩(wěn)定。而設(shè)備自動(dòng)化回歸流程可以與線下監(jiān)控完美的結(jié)合起來,首先每個(gè)版本可以確保運(yùn)行在同一款設(shè)備上,其次每個(gè)版本運(yùn)行的主流程用例基本上保持一致,這樣就為應(yīng)用“前后”版本性能數(shù)據(jù)分析對(duì)比提供了兩個(gè)參照條件。性能問題上報(bào)后,除了微信Robot通知相關(guān)干系人解決問題外,還基于移動(dòng)端 mPaaS 搭建了問題管理與分配平臺(tái),便于跟進(jìn)與追蹤。

    二、監(jiān)控指標(biāo)分析

    性能監(jiān)控目前對(duì)階段、流量、頁面耗時(shí)、 ANR 、慢方法、 fps 等數(shù)據(jù)做了實(shí)時(shí)監(jiān)控,本篇文章只會(huì)對(duì)階段、流量、頁面耗時(shí)進(jìn)行歸納分析,后面“有贊移動(dòng)性能監(jiān)控平臺(tái)系列文章“會(huì)對(duì) ANR 、慢方法、 fps 等監(jiān)控?cái)?shù)據(jù)進(jìn)行總結(jié)。

    2.1 階段數(shù)據(jù)

    移動(dòng)端每個(gè)業(yè)務(wù)流程都可以統(tǒng)稱為“階段”,比如 App 啟動(dòng)、商品加購、商品查詢等,業(yè)務(wù)方可以對(duì)自身需要關(guān)心的業(yè)務(wù)階段進(jìn)行監(jiān)控,結(jié)合“數(shù)據(jù)分析”與“告警能力”快速協(xié)助業(yè)務(wù)方排查問題。階段分析包括“方法耗時(shí)分析”與“網(wǎng)絡(luò)狀況分析”兩個(gè)部分,下面會(huì)具體介紹。

    2.1.1 方法耗時(shí)分析

    在 App 編譯期會(huì)對(duì)每個(gè)方法進(jìn)行前后打點(diǎn),確保運(yùn)行過程中每個(gè)階段方法耗時(shí)都可以被自動(dòng)統(tǒng)計(jì)出來,節(jié)省手動(dòng)打點(diǎn)統(tǒng)計(jì)成本。
    原理
    開發(fā) Gradle Plugin 插件,在 App 編譯 Transform 階段( .class 轉(zhuǎn)換為 .dex 過程),對(duì)字節(jié)碼進(jìn)行操作,在方法的開始執(zhí)行( methodEnter )與結(jié)束執(zhí)行( methodExit )通過 ASM 工具分別插入 MethodBeat 的 i 與 o 方法,對(duì)每個(gè)方法進(jìn)行首尾打點(diǎn),運(yùn)行時(shí)自動(dòng)統(tǒng)計(jì)方法耗時(shí)。
    分析詳情
    應(yīng)用所有版本產(chǎn)生的階段數(shù)據(jù)都會(huì)上傳到后端,后端會(huì)通過定式任務(wù)對(duì)階段數(shù)據(jù)進(jìn)行分析,分析角度分為新增、新減、陡增、陡降4個(gè)維度,協(xié)助開發(fā)綜合對(duì)問題進(jìn)行排查。啟動(dòng)階段舉例:

    2.1.2 網(wǎng)絡(luò)狀況分析

    業(yè)務(wù)方可以定義是否需要監(jiān)控階段的網(wǎng)絡(luò)狀況,比如啟動(dòng)階段,除了要監(jiān)控啟動(dòng)方法耗時(shí)之外,網(wǎng)絡(luò)狀態(tài)也需要進(jìn)行監(jiān)控( App 啟動(dòng)時(shí),硬件負(fù)載比較高,過多的網(wǎng)絡(luò) IO 請(qǐng)求會(huì)拖累啟動(dòng)速度)。
    原理
    有贊零售 App 網(wǎng)絡(luò)通過 OkHttp 進(jìn)行請(qǐng)求,通過自定義攔截器對(duì)網(wǎng)絡(luò)進(jìn)行統(tǒng)一攔截,統(tǒng)計(jì)每個(gè)階段網(wǎng)絡(luò)鏈接數(shù)量與請(qǐng)求耗時(shí), intercept 方法實(shí)現(xiàn)如下:
    public Response intercept(Chain chain) throws IOException {        Request request = chain.request();        Response response = null;        String url = getRequestUrl(request.url());        if (!TextUtils.isEmpty(url)) {            AppSegmentCache.INSTANCE.setRequestStart(url);            long startNs = System.nanoTime();            try {                response = chain.proceed(request);            } catch (Exception e) {                throw e;            }            long tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs);            AppSegmentCache.INSTANCE.setRequestEnd(url, tookMs);        }        return chain.proceed(request);    }
    分析詳情
    分為“全部調(diào)用”與"重復(fù)調(diào)用"兩個(gè)統(tǒng)計(jì)維度,“全部調(diào)用”會(huì)統(tǒng)計(jì)當(dāng)前版本該階段網(wǎng)絡(luò)請(qǐng)求總數(shù),且會(huì)與上個(gè)版本請(qǐng)求總數(shù)進(jìn)行比較,計(jì)算出升降趨勢(shì)(提升/下降了 x%),且列出“新增”與“新減”兩個(gè)數(shù)據(jù)維度,協(xié)助對(duì)網(wǎng)絡(luò)狀況進(jìn)行分析。“重復(fù)調(diào)用”會(huì)統(tǒng)計(jì)所有重復(fù)調(diào)用的接口狀況,包括網(wǎng)絡(luò)重復(fù)請(qǐng)求的總數(shù),還會(huì)全部列出重復(fù)調(diào)用鏈接內(nèi)容,方便業(yè)務(wù)方進(jìn)行排查優(yōu)化。

    2.2 流量

    App 運(yùn)行過程中主要涉及到接口、文本、視頻、圖片等各種流量請(qǐng)求,往往在開發(fā)過程中不太會(huì)注意流量消耗這個(gè)指標(biāo),最近也經(jīng)常有商家反饋 App 流量消耗比較大,但目前并不能準(zhǔn)確的定位流量消耗主因。

    2.2.1 原理

    分別對(duì) HttpUrlConnection 和 OkHttp 做 Hook ( .class -> .dex transform 流程插樁),所有的請(qǐng)求都得經(jīng)過 Hook 層,這樣就能統(tǒng)計(jì)每個(gè)請(qǐng)求的流量大小與 response 內(nèi)容,便于業(yè)務(wù)方進(jìn)行分析。
    OkHttpHook
    App 編譯期往 OkHttp 中配置 GlobalNetworkInterceptor 攔截器,統(tǒng)計(jì) response length(流量大?。?、response content(請(qǐng)求返回內(nèi)容,如果是 gzip 需要解壓),然后將流量內(nèi)容寫入文件中(非線上包才會(huì)采集),便于分析。
    internal object OkHttpHook {    @JvmField    public val globalNetworkInterceptor = Interceptor { chain ->    ... ...    // 計(jì)算repsonse length(流量大?。?/span>    // 讀取response content(如果是gzip需要解壓)    // 流量內(nèi)容寫入文件中    val fileUrl = File(file, URLEncoder.encode(SimpleDateFormat("yyyy-MM-dd-HH:mm:ss-SSS").format(Date()) + "-" + netPackInfo.url))    fileUrl.writeText(netPackInfo.toString())    ... ...}
    HttpUrlConnectHook
    編譯期對(duì) HttpUrlConnection 進(jìn)行 Hook ,底層網(wǎng)絡(luò)請(qǐng)求其實(shí)是代理到 OkhttpClient 上,這樣就能保證 HttpUrlConnection 所有網(wǎng)絡(luò)請(qǐng)求也能通過 OkHttp 進(jìn)行處理,這樣流量攔截器( GlobalNetworkInterceptor )就可以進(jìn)行復(fù)用了。
    public object HttpUrlConnectHook {    @JvmStatic    fun proxy(httpUrlConnection: URLConnection): URLConnection {        try {            return hookOkHttpURLConnection(httpUrlConnection)        } catch (e: Exception) {            e.printStackTrace()        }        return urlConnection    }}
    @Throws(Exception::class)private fun hookOkHttpURLConnection(httpUrlConnection: URLConnection): URLConnection { val builder = OkHttpClient.Builder() val mClient = builder .retryOnConnectionFailure(true ... ... .build() val strUrl = httpUrlConnection.url.toString() val url = URL(strUrl) val protocol = url.protocol.toLowerCase(Locale.ROOT) if (protocol.startWith("http", ignoreCase = true)) { return HttpUrlFactory.OkHttpURLConnection(url, mClient) } else urlConnection}

    2.2.2 分析詳情

    通過展示網(wǎng)絡(luò)各個(gè)統(tǒng)計(jì)指標(biāo)數(shù)據(jù)詳情,包括每個(gè)接口的請(qǐng)求流量大小、請(qǐng)求次數(shù)、請(qǐng)求內(nèi)容,便于技術(shù)人員對(duì)流量問題進(jìn)行分析。

    2.3 頁面耗時(shí)

    有贊零售面向B端的產(chǎn)品,適配了很多低端收銀機(jī),在頁面流暢性有嚴(yán)格要求,通過頁面耗時(shí)監(jiān)控,統(tǒng)計(jì)每個(gè)頁面( Activity | Fragment )的耗時(shí),當(dāng)頁面耗時(shí)超過閾值時(shí),會(huì)生成問題,分配給相應(yīng)的處理人進(jìn)行修復(fù)。

    2.3.1 原理

    監(jiān)控 Activity 與 Fragment onCreate() 方法開始執(zhí)行作為頁面繪制開始時(shí)機(jī),頁面 onDraw() 方法第一次回調(diào)時(shí)機(jī)作為頁面繪制結(jié)束時(shí)機(jī),兩個(gè)時(shí)機(jī)做減法,算出頁面渲染耗時(shí)。
    頁面監(jiān)控開始時(shí)機(jī)
    在 ActivityLifecycleCallbacks 全局監(jiān)聽 Activity 生命周期,在 onActivityCreated() 方法中調(diào)用 watchActivity() 方法,watchActivity 除了統(tǒng)一對(duì) Activity 頁面預(yù)埋開始時(shí)機(jī)外,還會(huì)區(qū)分 Activity 類型,對(duì) Activity 內(nèi)嵌的 Fragment 注冊(cè) FragmentLifecycleCallbacks 監(jiān)聽,同樣在 onFragmentViewCreate() 回調(diào)中對(duì)Fragment頁面開始時(shí)機(jī)進(jìn)行預(yù)埋。
    public void watchActivity(Activity activity) {    watchWithMonitorView(activity.getClass().getName(), activity.getWindow().getDecorView());     ... ...    if (activity instanceof android.support.v4.app.FragmentActivity) {            ((FragmentActivity) activity).getSupportFragmentManager().registerFragmentLifecycleCallbacks(new FragmentLifecycleCallbacks() {                    public void onFragmentViewCreated(android.support.v4.app.FragmentManager fm, final android.support.v4.app.Fragment f, View v,                                                      Bundle savedInstanceState) {                        watchWithMonitorView(f.getClass().getName(), v);                    }
    }), true); } ... ...}
    頁面監(jiān)控結(jié)束時(shí)機(jī)
    監(jiān)控頁面根布局 onDraw() 第一次回調(diào),定為頁面繪制結(jié)束時(shí)機(jī)。
    public void watchWithMonitorView(final String className, final View view) {        final long startTime = System.currentTimeMillis();        final WeakReference viewWeakReference = new WeakReference<>(view);        final ViewTreeObserver.OnDrawListener onDrawListener = new ViewTreeObserver.OnDrawListener() {            Boolean first = true;            @Override            public void onDraw() {                if (startTime != 0 && first && viewWeakReference.get() != null) {                ... ...            }        };        view.getViewTreeObserver().addOnDrawListener(onDrawListener);    }

    2.3.2 分析詳情

    在設(shè)備自動(dòng)化回歸過程中一個(gè)頁面會(huì)被多次調(diào)用,在線下監(jiān)控環(huán)境中,只有一個(gè)頁面3次超過耗時(shí)閾值( 200ms )才會(huì)算成有效的頁面卡頓問題,防止硬件不穩(wěn)定造成問題誤報(bào)。

    三、后臺(tái)問題分析

    設(shè)備自動(dòng)化回歸過程中產(chǎn)生的性能數(shù)據(jù)存在一定的波動(dòng)性,后臺(tái)需要對(duì)批量性能數(shù)據(jù)進(jìn)行算法校驗(yàn),評(píng)估出合理的有效問題,減少問題誤報(bào)。

    分析工作流程(階段數(shù)據(jù)分析舉例):

    設(shè)備自動(dòng)化回歸過程采集到階段數(shù)據(jù)后,上傳到移動(dòng)網(wǎng)關(guān),晚上7點(diǎn)啟動(dòng)定時(shí)任務(wù),在后臺(tái)拉取當(dāng)前應(yīng)用版本各個(gè)階段最近n條數(shù)據(jù),進(jìn)行數(shù)據(jù)聚合分析,計(jì)算出合理的階段耗時(shí)平均值,再同樣拉取當(dāng)前應(yīng)用上個(gè)版本各個(gè)階段的最近n條數(shù)據(jù),同樣算出階段耗時(shí)平均值,與當(dāng)前版本階段耗時(shí)平均值進(jìn)行對(duì)比,算出漲跌幅度,如果超出閾值就會(huì)當(dāng)成有效問題,進(jìn)行分配與告警。

    四、線下AWACS工具

    在 QA 與開發(fā)過程中, App 上會(huì)懸浮告警 ICON ,開發(fā)者可以點(diǎn)擊告警 ICON 打開性能監(jiān)控中心進(jìn)行數(shù)據(jù)查看。性能監(jiān)控中心會(huì)展示階段、 ANR 、慢方法、流量、 FPS 等性能數(shù)據(jù),便于開發(fā)對(duì)問題進(jìn)行排查。

    五、問題管理與分配平臺(tái)

    后臺(tái)對(duì)問題進(jìn)行分析后,如果是有效問題會(huì)落到后臺(tái) db 中,前臺(tái)在 mPaaS 搭建一套問題查看與分配 UI 看板,方便業(yè)務(wù)方對(duì)問題進(jìn)行處理與狀態(tài)跟進(jìn)。

    5.1 問題列表

    APM 監(jiān)控的所有性能指標(biāo)都可以在性能面板中進(jìn)行切換篩選, tab 選中后再結(jié)合應(yīng)用、狀態(tài)、環(huán)境篩選器列出問題列表。

    5.2 問題詳情

    點(diǎn)擊問題列表后跳轉(zhuǎn)到問題詳情,問題詳情中包含問題發(fā)生次數(shù)、進(jìn)度、詳細(xì)信息、設(shè)備基本信息等,協(xié)助開發(fā)定位問題。
    點(diǎn)擊問題詳情右上角“變更狀態(tài)”按鈕,可以變更問題狀態(tài),并可選擇負(fù)責(zé)人對(duì)問題進(jìn)行分配與跟進(jìn)。

    六、未來規(guī)劃

    1:監(jiān)控更多維度的數(shù)據(jù),包括 cpu 、線程、子線程更新 UI 等。
    2:增加更多的自動(dòng)化測(cè)試用例,針對(duì)特定的性能場(chǎng)景進(jìn)行獨(dú)立測(cè)試(現(xiàn)在測(cè)試用例基本上都是主流程,覆蓋度還不太夠)。
    3:補(bǔ)齊自動(dòng)化設(shè)備的數(shù)量與型號(hào),通過多機(jī)型綜合分析性能問題。
    4:推廣到公司內(nèi)部使用,協(xié)助解決有贊其他應(yīng)用端性能問題。

    end



    ?

    ??
    ?
    瀏覽 62
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    夜夜躁日日躁狠狠久久AV | 国语对白真实视频播放 | www.五月花 | 亚欧洲精品在线视频 | 久久极品视频 |