电竞比分网-中国电竞赛事及体育赛事平台

分享

#研發(fā)解決方案介紹#Tracing(鷹眼)

 WindySky 2017-12-13
鄭昀 最后更新于2014/11/12
關(guān)鍵詞:GoogleDapper、分布式跟蹤、鷹眼、Tracing、HBase、HDFS、

本文檔適用人員:研發(fā)
分布式系統(tǒng)為什么需要 Tracing?
  先介紹一個(gè)概念:分布式跟蹤,或分布式追蹤
  電商平臺(tái)由數(shù)以百計(jì)的分布式服務(wù)構(gòu)成,每一個(gè)請(qǐng)求路由過來后,會(huì)經(jīng)過多個(gè)業(yè)務(wù)系統(tǒng)并留下足跡,并產(chǎn)生對(duì)各種Cache或DB的訪問,但是這些分散的數(shù)據(jù)對(duì)于問題排查,或是流程優(yōu)化都幫助有限。對(duì)于這么一個(gè)跨進(jìn)程/跨線程的場(chǎng)景,匯總收集并分析海量日志就顯得尤為重要。要能做到追蹤每個(gè)請(qǐng)求的完整調(diào)用鏈路,收集調(diào)用鏈路上每個(gè)服務(wù)的性能數(shù)據(jù),計(jì)算性能數(shù)據(jù)和比對(duì)性能指標(biāo)(SLA),甚至在更遠(yuǎn)的未來能夠再反饋到服務(wù)治理中,那么這就是分布式跟蹤的目標(biāo)了。在業(yè)界,twitter 的 zipkin 和淘寶的鷹眼就是類似的系統(tǒng),它們都起源于 Google Dapper 論文,就像歷史上 Hadoop 發(fā)源于 Google Map/Reduce 論文,HBase 源自 Google BigTable 論文一樣。
  好了,整理一下,Google叫Dapper,淘寶叫鷹眼,Twitter叫ZipKin,京東商城叫Hydra,eBay叫Centralized Activity Logging (CAL),大眾點(diǎn)評(píng)網(wǎng)叫CAT,我們叫Tracing。
  這樣的系統(tǒng)通常有幾個(gè)設(shè)計(jì)目標(biāo):
(1)低侵入性——作為非業(yè)務(wù)組件,應(yīng)當(dāng)盡可能少侵入或者無侵入其他業(yè)務(wù)系統(tǒng),對(duì)于使用方透明,減少開發(fā)人員的負(fù)擔(dān);
(2)靈活的應(yīng)用策略——可以(最好隨時(shí))決定所收集數(shù)據(jù)的范圍和粒度;
(3)時(shí)效性——從數(shù)據(jù)的收集和產(chǎn)生,到數(shù)據(jù)計(jì)算和處理,再到最終展現(xiàn),都要求盡可能快;
(4)決策支持——這些數(shù)據(jù)是否能在決策支持層面發(fā)揮作用,特別是從 DevOps 的角度;
(5)可視化才是王道。
先來一個(gè)直觀感受:
  下面依次展示了 ZipKin、鷹眼、窩窩的調(diào)用鏈繪制界面。
圖1 twitter zipkin 調(diào)用鏈
圖2 淘寶鷹眼的調(diào)用鏈
圖3 京東商城hydra調(diào)用鏈
圖4 窩窩tracing調(diào)用鏈
  鼠標(biāo)移動(dòng)到調(diào)用鏈的每一層點(diǎn)擊,可以看到執(zhí)行時(shí)長(zhǎng)、宿主機(jī)IP、數(shù)據(jù)庫操作、傳入?yún)?shù)甚至錯(cuò)誤堆棧等等具體信息。

淘寶如何實(shí)現(xiàn)的:
  同一次請(qǐng)求的所有相關(guān)調(diào)用的情況,在淘寶 EagleEye 里稱作 調(diào)用鏈。同一個(gè)時(shí)刻某一臺(tái)服務(wù)器并行發(fā)起的網(wǎng)絡(luò)調(diào)用有很多,怎么識(shí)別這個(gè)調(diào)用是屬于哪個(gè)調(diào)用鏈的呢?可以在各個(gè)發(fā)起網(wǎng)絡(luò)調(diào)用的中間件上下手。

  在前端請(qǐng)求到達(dá)服務(wù)器時(shí),應(yīng)用容器在執(zhí)行實(shí)際業(yè)務(wù)處理之前,會(huì)先執(zhí)行 EagleEye 的埋點(diǎn)邏輯(類似 Filter 的機(jī)制),埋點(diǎn)邏輯為這個(gè)前端請(qǐng)求分配一個(gè)全局唯一的調(diào)用鏈ID。這個(gè)ID在 EagleEye 里面被稱為 TraceId,埋點(diǎn)邏輯把 TraceId 放在一個(gè)調(diào)用上下文對(duì)象里面,而調(diào)用上下文對(duì)象會(huì)存儲(chǔ)在 ThreadLocal 里面。調(diào)用上下文里還有一個(gè)ID非常重要,在 EagleEye 里面被稱作 RpcId。RpcId 用于區(qū)分同一個(gè)調(diào)用鏈下的多個(gè)網(wǎng)絡(luò)調(diào)用的發(fā)生順序和嵌套層次關(guān)系。對(duì)于前端收到請(qǐng)求,生成的 RpcId 固定都是0

  當(dāng)這個(gè)前端執(zhí)行業(yè)務(wù)處理需要發(fā)起 RPC 調(diào)用時(shí),淘寶的 RPC 調(diào)用客戶端 HSF 會(huì)首先從當(dāng)前線程 ThreadLocal 上面獲取之前 EagleEye 設(shè)置的調(diào)用上下文。然后,把 RpcId 遞增一個(gè)序號(hào)。在 EagleEye 里使用多級(jí)序號(hào)來表示 RpcId,比如前端剛接到請(qǐng)求之后的 RpcId 是0,那么 它第一次調(diào)用 RPC 服務(wù)A時(shí),會(huì)把 RpcId 改成 0.1。之后,調(diào)用上下文會(huì)作為附件隨這次請(qǐng)求一起發(fā)送到遠(yuǎn)程的 HSF 服務(wù)器。

  HSF 服務(wù)端收到這個(gè)請(qǐng)求之后,會(huì)從請(qǐng)求附件里取出調(diào)用上下文,并放到當(dāng)前線程 ThreadLocal 上面。如果服務(wù)A在處理時(shí),需要調(diào)用另一個(gè)服務(wù),這個(gè)時(shí)候它會(huì)重復(fù)之前提到的操作,唯一的差別就是 RpcId 會(huì)先改成 0.1.1 再傳過去。服務(wù)A的邏輯全部處理完畢之后,HSF 在返回響應(yīng)對(duì)象之前,會(huì)把這次調(diào)用情況以及 TraceId、RpcId 都打印到它的訪問日志之中,同時(shí),會(huì)從 ThreadLocal 清理掉調(diào)用上下文。如圖6-1展示了一個(gè)瀏覽器請(qǐng)求可能觸發(fā)的系統(tǒng)間調(diào)用。

圖6-1-一個(gè)瀏覽器請(qǐng)求可能觸發(fā)的系統(tǒng)間調(diào)用

  圖6-1描述了 EagleEye 在一個(gè)非常簡(jiǎn)單的分布式調(diào)用場(chǎng)景里做的事情,就是為每次調(diào)用分配 TraceId、RpcId,放在 ThreadLocal 的調(diào)用上下文上面,調(diào)用結(jié)束的時(shí)候,把 TraceId、RpcId 打印到訪問日志。類似的其他網(wǎng)絡(luò)調(diào)用中間件的調(diào)用過程也都比較類似,這里不再贅述了。訪問日志里面,一般會(huì)記錄調(diào)用時(shí)間、遠(yuǎn)端IP地址、結(jié)果狀態(tài)碼、調(diào)用 耗時(shí)之類,也會(huì)記錄與這次調(diào)用類型相關(guān)的一些信息,如URL、服 務(wù)名、消息topic等。很多調(diào)用場(chǎng)景會(huì)比上面說的完全同步的調(diào)用更為復(fù)雜,比如會(huì)遇到異步、單向、廣播、并發(fā)、批處理等等,這時(shí)候需要妥善處理好 ThreadLocal 上的調(diào)用上下文,避免調(diào)用上下文混亂和無法正確釋放。另外,采用多級(jí)序號(hào)的 RpcId 設(shè)計(jì)方案會(huì)比單級(jí)序號(hào)遞增更容易準(zhǔn)確還原當(dāng)時(shí)的調(diào)用情況。

  最后,EagleEye 分析系統(tǒng)把調(diào)用鏈相關(guān)的所有訪問日志都收集上來,按 TraceId 匯總在一起之后,就可以準(zhǔn)確還原調(diào)用當(dāng)時(shí)的情況了。

圖6-2-一個(gè)典型的調(diào)用鏈

  如圖6-2所示,就是采集自淘寶線上環(huán)境的某一條實(shí)際調(diào)用鏈。調(diào)用鏈通過樹形展現(xiàn)了調(diào)用情況。調(diào)用鏈可以清晰地看到當(dāng)前請(qǐng)求的調(diào)用情況,幫助問題定 位。如上圖,mtop應(yīng)用發(fā)生錯(cuò)誤時(shí),在調(diào)用鏈上可以直接看出這是因?yàn)榈谒膶拥囊粋€(gè)(tair@1)請(qǐng)求導(dǎo)致網(wǎng)絡(luò)超時(shí),使最上層頁面出現(xiàn)超時(shí)問題。這種調(diào) 用鏈,可以在 EagleEye 系統(tǒng)監(jiān)測(cè)到包含異常的訪問日志后,把當(dāng)前的錯(cuò)誤與整個(gè)調(diào)用鏈關(guān)聯(lián)起來。問題排查人員在發(fā)現(xiàn)入口錯(cuò)誤量上漲或耗時(shí)上升時(shí),通過  EagleEye 查找出這種包含錯(cuò)誤的調(diào)用鏈采樣,提高故障定位速度。

調(diào)用鏈數(shù)據(jù)在容量規(guī)劃和穩(wěn)定性方面的分析

  如果對(duì)同一個(gè)前端入口的多條調(diào)用鏈做匯總統(tǒng)計(jì),也就是說,把這個(gè)入口URL下面的所有調(diào)用按照調(diào)用鏈的樹形結(jié)構(gòu)全部疊加在一起,就可以得到一個(gè)新的樹結(jié)構(gòu)(如圖6-3所示)。這就是入口下面的所有依賴的調(diào)用路徑情況。

圖6-3-對(duì)某個(gè)入口的調(diào)用鏈做統(tǒng)計(jì)之后得到的依賴分析

  這種分析能力對(duì)于復(fù)雜的分布式環(huán)境的調(diào)用關(guān)系梳理尤為重要。傳統(tǒng)的調(diào)用統(tǒng)計(jì)日志是按固定時(shí)間窗口預(yù)先做了統(tǒng)計(jì)的日志,上面缺少了鏈路細(xì)節(jié)導(dǎo)致沒辦法對(duì)超過 兩層以上的調(diào)用情況進(jìn)行分析。例如,后端數(shù)據(jù)庫就無法評(píng)估數(shù)據(jù)庫訪問是來源于最上層的哪些入口;每個(gè)前端系統(tǒng)也無法清楚確定當(dāng)前入口由于雙十一活動(dòng)流量翻 倍,會(huì)對(duì)后端哪些系統(tǒng)造成多大的壓力,需要分別準(zhǔn)備多少機(jī)器。有了 EagleEye 的數(shù)據(jù),這些問題就迎刃而解了。
  下圖6-4展示了數(shù)據(jù)流轉(zhuǎn)過程。
圖6-4 鷹眼的數(shù)據(jù)收集和存儲(chǔ)
京東如何實(shí)現(xiàn)的: 
  京東商城引入了阿里開源的服務(wù)治理中間件 Dubbo,所以它的分布式跟蹤 Hydra 基于 Dubbo 就能做到對(duì)業(yè)務(wù)系統(tǒng)幾乎無侵入了。
  Hydra 的領(lǐng)域模型如下圖7所示:
圖7 hydra 領(lǐng)域模型以及解釋
  hydra 數(shù)據(jù)存儲(chǔ)是 HBase,如下圖8所示:
圖8 hydra 架構(gòu)
窩窩如何實(shí)現(xiàn)的: 
  2012年,逐漸看到自建分布式跟蹤系統(tǒng)的重要性,但隨即意識(shí)到如果沒有對(duì) RPC 調(diào)用框架做統(tǒng)一封裝,就可能侵入到每一個(gè)業(yè)務(wù)工程里去寫埋點(diǎn)日志,于是推廣 Dubbo 也提上日程。2013年,確定系統(tǒng)建設(shè)目標(biāo),開始動(dòng)手。由于 tracing 跟 DevOps 息息相關(guān),所以數(shù)據(jù)聚合、存儲(chǔ)、分析和展示由運(yùn)維部向榮牽頭開發(fā),各個(gè)業(yè)務(wù)工程數(shù)據(jù)埋點(diǎn)和上報(bào)由研發(fā)部國璽負(fù)責(zé)。
  經(jīng)過后續(xù)向榮、劉卓、國璽、明斌等人的不斷改進(jìn),技術(shù)選型大致如下所示。
  • 埋點(diǎn)
    • 實(shí)現(xiàn)線程內(nèi) trace 上下文傳遞,即服務(wù)器內(nèi)部的方法互調(diào)時(shí)不需要強(qiáng)制在方法形參中加 Message 參數(shù);
    • 實(shí)現(xiàn) trace 埋點(diǎn)邏輯自動(dòng)織入功能,即業(yè)務(wù)開發(fā)人員不需要在方法中打印 trace 日志,只需要給該方法加注解標(biāo)識(shí) ;
    • 原理:
      • 利用 Javaagent 機(jī)制,執(zhí)行 main 方法之前,會(huì)先執(zhí)行 premain 方法,在該方法中將字節(jié)碼轉(zhuǎn)換器載入 instrumentation,而后 jvm 在加載 class 文件之前都會(huì)先執(zhí)行字節(jié)碼轉(zhuǎn)換器。
      • 字節(jié)碼轉(zhuǎn)換器中的邏輯為,識(shí)別出注解 trace 的類及方法,并修改該方法字節(jié)碼,織入埋點(diǎn)邏輯。進(jìn)入方法時(shí)會(huì)初始 trace 上下文信息,并存儲(chǔ)在線程的 threadLocals 中,退出方法會(huì)打印 trace 日志并清空該方法的上下文。
  • 數(shù)據(jù)聚合
    • 應(yīng)用層 trace 日志通過 flume agents 實(shí)時(shí)發(fā)送至 flume collector;
  • 數(shù)據(jù)存儲(chǔ)
    • 服務(wù)端分別通過 hdfs-sink 和 hbase-sink,實(shí)時(shí)錄入至 hbase、hdfs;
    • hdfs 有 tmp 臨時(shí)文件存放實(shí)時(shí)聚合過來的數(shù)據(jù),每5分鐘生成一個(gè) done 文件;
  • 數(shù)據(jù)分析和統(tǒng)計(jì)
    • load 程序每 4 分鐘檢查 done 文件并存放至 hive 表 hkymessage 指定分區(qū);
    • 分析程序每5分鐘執(zhí)行一次, 將生成統(tǒng)計(jì)數(shù)據(jù)入庫, 結(jié)果集數(shù)據(jù)如下:
      數(shù)據(jù)格式:{5個(gè)分層的5個(gè)響應(yīng)時(shí)段請(qǐng)求個(gè)數(shù)合集}   {5個(gè)分層5-10s和大于10s散點(diǎn)數(shù)據(jù)合集}  當(dāng)前5分鐘最后一次請(qǐng)求rootid  統(tǒng)計(jì)時(shí)間
  • 數(shù)據(jù)展示
    • 基于 Python 的 Django
基于這些數(shù)據(jù)分析和統(tǒng)計(jì),我們就能繪制性能曲線圖,從中可以發(fā)現(xiàn)哪些時(shí)間點(diǎn)哪些層有性能問題,然后一路點(diǎn)進(jìn)去,直到找到到底是哪一個(gè)調(diào)用鏈里的哪一個(gè)環(huán)節(jié)慢。
圖9 性能曲線默認(rèn)圖形
  還可以從每一次調(diào)用結(jié)果分析出各層的異常曲線,并按照 memcached/redis/mongodb/mysql/runtime/fail 分類查看。
圖10 異常曲線默認(rèn)圖形
  還可以進(jìn)一步統(tǒng)計(jì)各個(gè)業(yè)務(wù)工程的訪問量、訪問質(zhì)量和平均訪問時(shí)長(zhǎng),并于歷史同期對(duì)比,從而快速理解系統(tǒng)服務(wù)質(zhì)量。
  如上所述,窩窩的 Tracing(鷹眼) 系統(tǒng)目前已投入使用,歸并在 OAP(運(yùn)維自動(dòng)化平臺(tái))里。
-over-

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多