成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

線程剖析 - 助力定位代碼層面高耗時問題

開發(fā) 前端
線程剖析的自身監(jiān)控指標(biāo),這些指標(biāo)有助于更好地了解剖析功能的性能和繁忙程度,以便進(jìn)行決策和調(diào)優(yōu)。線程剖析不僅提供了性能數(shù)據(jù),還可以與 OpenTelemetry 相結(jié)合,實現(xiàn)鏈路特征的關(guān)聯(lián),從而更全面地理解性能問題。

在當(dāng)今的軟件開發(fā)領(lǐng)域,性能問題是一個永不過時的挑戰(zhàn)。為了解決這一挑戰(zhàn),開發(fā)人員需要深入了解他們的應(yīng)用程序運行時的性能,并快速定位高耗時問題。線程剖析是一種強大的工具,通過采集和計算運行時線程棧,可以幫助開發(fā)人員更好地理解和解決性能問題。本文將深入探討線程剖析的基本思想和實現(xiàn)思路,以及客戶端和服務(wù)端的設(shè)計。

一、基本思想

線程剖析的核心思想是在業(yè)務(wù)線程執(zhí)行請求時創(chuàng)建一個特定閾值觸發(fā)的檢測任務(wù),用于監(jiān)測高耗時問題。如果任務(wù)未被取消,在達(dá)到高耗時閾值時,將有專門的線程去執(zhí)行剖析任務(wù),采集業(yè)務(wù)線程的堆棧,并異步發(fā)送給剖析服務(wù)端進(jìn)行計算,以估算出棧上的各個方法耗時。這個工具不僅提供了詳細(xì)的性能數(shù)據(jù),還能與開放遙測(OpenTelemetry)結(jié)合,從而實現(xiàn)鏈路特征的關(guān)聯(lián),主要流程如下:

圖片圖片

二、實現(xiàn)思路

客戶端設(shè)計

客戶端的架構(gòu)主要體現(xiàn)在任務(wù)的創(chuàng)建、調(diào)度、執(zhí)行和導(dǎo)出四個環(huán)節(jié)。

創(chuàng)建&調(diào)度任務(wù)

業(yè)務(wù)線程執(zhí)行時,若滿足指定要監(jiān)控的接口或線程名稱,將構(gòu)造一個包含該線程對象的檢測任務(wù)放入隊列,時間輪的工作線程會周期性(默認(rèn)100ms)在輪盤上移動一格,類似我們平時看到的鐘表上的指針那樣,每個周期會從任務(wù)隊列取出所有任務(wù),將各個任務(wù)分配添加到時間輪中每個格子中。如下圖所示:

圖片圖片

執(zhí)行任務(wù)

分配完成后,由任務(wù)執(zhí)行線程池的線程去執(zhí)行當(dāng)前周期所屬格子的所有任務(wù)。在執(zhí)行前,業(yè)務(wù)線程可能優(yōu)先結(jié)束而取消該任務(wù)的執(zhí)行,例如在達(dá)到耗時閾值后,剖析任務(wù)已經(jīng)或準(zhǔn)備開始執(zhí)行,但主線程取消了剖析任務(wù)這樣一個臨界點,此時可通過各語言的同步機制來及時取消剖析任務(wù)。

任務(wù)執(zhí)行時,剖析線程將周期性采集線程的堆棧,而為了方便后續(xù)的分析工作,也會同時記錄當(dāng)前堆棧產(chǎn)生的時間戳,直到業(yè)務(wù)線程發(fā)出中斷通知,或采集樣本數(shù)達(dá)到上限,或任務(wù)狀態(tài)發(fā)生改變,然后中斷剖析線程的執(zhí)行。

執(zhí)行完成后,將采集到的線程棧集 push 到診斷數(shù)據(jù)隊列,等待數(shù)據(jù)導(dǎo)出線程消費此隊列,并發(fā)送到服務(wù)端。這里需要注意,線程棧數(shù)據(jù)文本量一般不會太小,比如我們一個專門用于測試的應(yīng)用,500ms 觸發(fā)的閾值下的 HTTP 接口,每次請求讓線程隨機 Sleep 5s 以內(nèi),當(dāng)接口耗時超過 3s,單次剖析產(chǎn)生的棧文本大小在 200KB 以上,因此這里需要有個參數(shù),來控制隊列默認(rèn)長度,避免過多的堆棧快照擠兌內(nèi)存。

整個任務(wù)執(zhí)行流程如下圖所示:

圖片圖片

數(shù)據(jù)預(yù)聚合&導(dǎo)出

預(yù)聚合工作將由獨立的工作線程消費診斷數(shù)據(jù)隊列后來做,即將多個線程快照合并為一個,降低網(wǎng)絡(luò) IO 開銷。具體就是對于快照集中每個快照的棧幀,按照它的開始時間取快照集中相同棧幀的最小值,結(jié)束時間取快照集中相同棧幀的最大值這個規(guī)則進(jìn)行聚合,流程如下圖所示:

圖片圖片

而數(shù)據(jù)發(fā)送層就比較簡單了,采用高性能無鎖隊列 Mpsc, 使用 gRPC 協(xié)議發(fā)送到診斷服務(wù)端:

圖片圖片

當(dāng)然,為了降低業(yè)務(wù)系統(tǒng)的壓力,也可以將原始數(shù)據(jù)直接落盤,由外部獨立的采集器逐行采集然后發(fā)送到消息隊列。

服務(wù)端設(shè)計

圖片圖片

服務(wù)端的架構(gòu)主要考慮三個點:

數(shù)據(jù)接收

同 Otel 對 Trace 數(shù)據(jù)的處理思路類似,診斷數(shù)據(jù)發(fā)送請求需要快速地被響應(yīng),來減少客戶端因請求延遲導(dǎo)致發(fā)送隊列數(shù)據(jù)被丟棄的可能。因此,診斷服務(wù)端采用吞吐性能較好的 go 語言編寫,而請求涉及到跨語言調(diào)用,協(xié)議層上,綜合高效快速可靠因素,選用較成熟的 gRPC 協(xié)議進(jìn)行通信。

數(shù)據(jù)接收并成功解析后,需異步將數(shù)據(jù)放入隊列,這里我們選用采用了多副本機制的 Kafka 消息中間件,來滿足診斷服務(wù)各模塊之間的解耦,同時也保證診斷數(shù)據(jù)不丟失 。

數(shù)據(jù)解析&加工

診斷剖析數(shù)據(jù)消費組會去消費隊列中的數(shù)據(jù),將數(shù)據(jù)進(jìn)行進(jìn)一步解析,并且持久化處理,其中包括:

  • a) 父子棧幀推導(dǎo)

客戶端的預(yù)聚合會將多個快照合并為一個,因此快照內(nèi)的每個棧幀將擁有不同的起始和結(jié)束時間。由于 Java 的原始線程堆棧是無層級的結(jié)構(gòu),為了提高數(shù)據(jù)的可讀性,進(jìn)一步降低高耗時問題定位發(fā)現(xiàn)的成本,因此需將已合并的堆棧進(jìn)一步推導(dǎo)為包含父子棧幀的結(jié)構(gòu)化信息,即從棧頂?shù)牡诙€棧幀開始遍歷調(diào)用棧,若當(dāng)前棧幀的快照開始和結(jié)束的時間范圍位于上個棧幀的左開右閉或左閉右開區(qū)間,則將當(dāng)前棧幀設(shè)置為上個棧幀的子棧:

圖片圖片

注意:

1. 一個 Java 線程的大部分調(diào)用棧形式本身就是個從 "Thread.run" 開始的嵌套,而每次快照時也無從得知層級信息,因此不考慮推導(dǎo)快照開始和結(jié)束時間完全一致的棧幀,將這些棧幀置為同級即可。

2. 使用線程的快照時間來推導(dǎo)還原父子棧和耗時仍然是個相對比較粗略的統(tǒng)計行為,其精度受到當(dāng)前線程調(diào)用??煺諏?dǎo)出的耗時,以及每次快照的間隔耗時的影響,因此父子層級結(jié)果僅供參考,并不絕對等于實際調(diào)用的關(guān)系結(jié)果。

  • b) 自身耗時計算

當(dāng)已推導(dǎo)出父子棧幀關(guān)系后,可對結(jié)果集進(jìn)行遍歷,計算自身耗時,計算規(guī)則如下:

  • 從第二個棧幀開始,如果與上一個棧幀的快照開始和結(jié)束時間一致,則上個棧幀的自身耗時設(shè)為 0,否則會將當(dāng)前棧幀的父棧幀(若存在)的自身耗時減掉上個棧幀的自身耗時。
  • 如果當(dāng)前棧幀是最后一個,則將當(dāng)前棧幀自身耗時設(shè)為快照開始與結(jié)束的時間差,并且將當(dāng)前棧幀的父棧幀(若存在)的自身耗時減掉當(dāng)前棧幀的自身耗時。
  • 如果當(dāng)前棧幀有子棧幀,處理方式同上。

以上圖調(diào)用時序為例,根據(jù)以上規(guī)則得出的自身耗時計算示意圖如下:

圖片圖片

  • c) 數(shù)據(jù)持久化

當(dāng)完成父子棧幀推導(dǎo)和自身耗時計算后,數(shù)據(jù)將持久化存儲,例如將數(shù)據(jù)存儲到 ClickHouse,供數(shù)據(jù)查詢端使用。

數(shù)據(jù)查詢

診斷剖析數(shù)據(jù)將以 HTTP API 形式對外提供查詢服務(wù),例如可觀測性門戶系統(tǒng),可根據(jù)線程名,鏈路 Trace ID, Span ID 等特征進(jìn)行剖析數(shù)據(jù)的查詢。

[
    {
        "data": "YXQgc3VuLm5pby5jaC5Vd...",//線程剖析棧
        "thread_name": "XNIO-1 I/O-1",//線程名稱
        "thread_state": "RUNNABLE",//線程狀態(tài)
        "trigger_millisecond": 500,//觸發(fā)閾值
        "self_millisecond": 38,//自身耗時
        "source_snapshot_count": 153//快照數(shù)
    },
    {
        "data": "YXQgaW8udW5kZXJ0b3cuc2Vy...",
        "thread_name": "XNIO-1 task-1",
        "thread_state": "RUNNABLE",
        "trigger_millisecond": 500,
        "self_millisecond": 0,
        "source_snapshot_count": 140
    }
]

調(diào)用鏈關(guān)聯(lián)

線程剖析能結(jié)合 OpenTelemetry ,借助 OpenTelemetry Java Instrumentation 上下文的生命周期,從而關(guān)聯(lián) Trace ID 、接口名等鏈路特征。

圖片圖片

自身監(jiān)控指標(biāo)

線程剖析功能需要擁有較完善的自身監(jiān)控,以便觀測復(fù)雜剖析流程下對業(yè)務(wù)系統(tǒng)潛在的性能影響。這些監(jiān)控包括:

  • 任務(wù)檢測隊列大小

檢測隊列用于給時間輪提供任務(wù),該指標(biāo)的大小給線程剖析的采樣,接口名,線程名稱等條件提供了一定參考。

圖片圖片

  • 任務(wù)釋放平均耗時

剖析任務(wù)的釋放將會中斷正在執(zhí)行的剖析任務(wù),其中涉及到剖析、數(shù)據(jù)狀態(tài)機的改變,線程的中斷。多線程情況下,需保證操作的原子性,如果任務(wù)釋放的平均耗時變長,則能反映當(dāng)前業(yè)務(wù)系統(tǒng) CPU 線程上下文切換效率下降。

圖片圖片

  • 正在執(zhí)行剖析任務(wù)的個數(shù)

線程剖析是以線程為單位來執(zhí)行的,通過觀測正在進(jìn)行線程剖析的任務(wù)數(shù),可反映出剖析功能繁忙的程度,以及幫助我們決策是否需要對同時剖析的任務(wù)數(shù)進(jìn)行限制。

圖片圖片

  • 線程堆棧導(dǎo)出平均耗時

線程棧導(dǎo)出方法的平均耗時,如果該操作耗時顯著升高,且調(diào)用棧未有明顯變化,則代表性能惡化。

圖片圖片

  • 數(shù)據(jù)隊列大小

指待發(fā)送到服務(wù)端的數(shù)據(jù)隊列大小。

  • 數(shù)據(jù)入隊速率

指待發(fā)送到服務(wù)端的數(shù)據(jù)入隊的速率。

  • 數(shù)據(jù)合并平均耗時

數(shù)據(jù)發(fā)送前進(jìn)行預(yù)聚合,將多個線程快照合并為一個,這個過程的平均耗時,該值可供剖析條件提供一定參考。

圖片圖片

  • 線程??煺諏?dǎo)出發(fā)送平均字節(jié)

線程快照發(fā)送的請求包平均大小。

圖片圖片

  • 數(shù)據(jù)導(dǎo)出速率

線程快照發(fā)送的速率。

圖片圖片

對以上指標(biāo)進(jìn)行監(jiān)控,也方便對相關(guān)參數(shù)進(jìn)行調(diào)優(yōu),從而更好地在診斷剖析功能的完整性與服務(wù)性能之間做相關(guān)取舍。

三、結(jié)語

線程剖析為解決性能問題提供了有力支持。通過采集和分析線程棧信息,它能夠幫助開發(fā)人員定位應(yīng)用程序中的高耗時問題,為性能優(yōu)化提供關(guān)鍵信息。本文詳細(xì)介紹了線程剖析的基本思想和實現(xiàn)思路,以及客戶端和服務(wù)端的設(shè)計架構(gòu)。其核心思想是通過創(chuàng)建特定閾值觸發(fā)的檢測任務(wù),監(jiān)測高耗時問題,并將采集到的數(shù)據(jù)異步發(fā)送到剖析服務(wù)端進(jìn)行進(jìn)一步計算和分析。

此外,線程剖析的自身監(jiān)控指標(biāo),這些指標(biāo)有助于更好地了解剖析功能的性能和繁忙程度,以便進(jìn)行決策和調(diào)優(yōu)。線程剖析不僅提供了性能數(shù)據(jù),還可以與 OpenTelemetry 相結(jié)合,實現(xiàn)鏈路特征的關(guān)聯(lián),從而更全面地理解性能問題。

總的來說,線程剖析可以幫助開發(fā)人員提高應(yīng)用程序的質(zhì)量和性能,快速定位性能問題,以確保應(yīng)用程序的順暢運行,同時,也可以更有效地應(yīng)對性能挑戰(zhàn),提高應(yīng)用程序的可維護(hù)性和性能。

責(zé)任編輯:武曉燕 來源: 得物技術(shù)
相關(guān)推薦

2010-02-05 18:00:18

Android源代碼

2010-02-04 10:19:39

C++多線程

2021-04-15 09:07:52

hotspotJavaC++

2025-03-06 00:00:05

DPIHD開發(fā)

2010-08-25 14:56:15

CSS相對定位

2011-07-21 11:12:58

iPhone 線程 多線程

2022-03-25 07:39:09

OSMySQL層面

2017-09-21 17:15:18

互聯(lián)網(wǎng)

2020-08-13 08:45:09

多線程死鎖

2010-11-04 10:05:48

2023-01-11 07:54:09

GC搜索代碼

2025-03-20 10:43:21

2015-07-08 10:37:12

MySQL高可用架構(gòu)業(yè)務(wù)架構(gòu)

2010-02-01 13:34:59

Python 腳本

2024-12-12 09:24:28

RocksDB服務(wù)器

2010-05-27 12:58:07

SVN升級

2010-03-12 14:28:45

Python if語句

2010-01-26 17:53:30

Android代碼結(jié)構(gòu)

2022-07-24 14:30:16

數(shù)據(jù)治理5G網(wǎng)絡(luò)VoNR
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 欧美日韩不卡合集视频 | 亚洲国产一区在线 | 欧美激情久久久 | 浴室洗澡偷拍一区二区 | 国产99久久精品一区二区永久免费 | 韩国久久 | 亚洲视频免费在线看 | 成年人在线观看 | 国产日产精品一区二区三区四区 | 男人天堂久久久 | 日韩欧美精品 | 亚洲啪啪| 在线日韩欧美 | 国产精品久久久久久婷婷天堂 | 免费看黄视频网站 | 免费人成在线观看网站 | 成人av免费网站 | 97国产在线观看 | 精品无码久久久久久国产 | 亚洲高清在线 | 国产一区二区三区精品久久久 | 亚洲www啪成人一区二区麻豆 | 亚洲人在线观看视频 | 最新伦理片 | 黄色大片免费网站 | 亚洲精品久久国产高清情趣图文 | 黄色免费看 | 亚洲www啪成人一区二区麻豆 | 亚洲精品一区二区三区中文字幕 | 国产成人精品一区二三区在线观看 | 91精品国产91综合久久蜜臀 | 国产精品亚洲精品久久 | 免费a级毛片在线播放 | 色欧美综合 | 亚洲国产欧美精品 | 色婷婷综合久久久久中文一区二区 | 国产午夜在线观看 | 九九热在线观看视频 | 天天久 | 精品中文在线 | 四虎成人精品永久免费av九九 |