天天看點

基礎篇丨鍊路追蹤(Tracing)其實很簡單

作者:阿裡開發者

作者:涯海

一、分布式鍊路追蹤的起源

當周末躺在被窩裡,點外賣時;雙 11 的零點,瘋狂送出訂單時;假期和基友激情開黑,五殺超神…在這個精彩紛呈的網際網路世界裡,這些應用背後又隐藏着什麼?每一次點選行為在 IT 世界裡會流經哪些節點,調用哪些服務,帶來哪些變化?這一切龐雜且精密,超出了人力探索的邊界,而分布式鍊路追蹤就是追溯請求在 IT 系統間流轉路徑與狀态的一門技術。接下來,讓我們通過對分布式鍊路追蹤的來了解這個 IT 世界!

說到分布式鍊路追蹤,就繞不開分布式系統與微服務的興起。早期 IT 系統非常簡單,幾乎所有程式都運作在同一個節點,互相之間也沒有什麼依賴。但随着硬體技術突飛猛進,硬體成本大幅下降,軟體複雜度卻越來越高。單一系統性能無法滿足複雜的資料計算任務,而軟體邏輯的複雜性也導緻維護成本大幅上升。另外,單節點的可靠性也難以保障,不可避免的會偶爾出現當機等行為,影響軟體的可用性。“性能、可維護性和可用性”這三大因素促使了分布式系統與微服務的誕生。

為了解決上述問題,人們很自然想到:既然一個硬體節點無法很好的運作軟體,那能不能夠通過多個節點來共同完成?并且為不同節點分派不同任務去提高效率。就好比通過不同角色分工協同的汽車生産流水線,分布式系統與微服務的理念亦是如此,如下圖所示。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

分布式系統與微服務自誕生就被廣泛應用,主要得益于以下優勢:

  • 擴充性

分布式系統天然具備“按需擴充”的能力,比如雙 11 大促前通過添加機器實作快速水準擴容,大促結束後釋放機器,充分利用雲計算的分時複用能力,節約成本。利用微服務,還可以實作按需精準擴容,比如登入服務擴容 10 倍,下單服務擴容3倍,最大化的節省資源。

  • 可靠性

分布式系統可以有效抵抗“單點風險”,不會因為某一個節點的故障,影響整體的服務可用性。結合流量排程、離群執行個體摘除和彈性擴容等技術,甚至可以實作故障自愈。

  • 可維護性

分布式系統可維護性更強,一方面我們将一個複雜服務拆分成多個簡單的微服務,每個微服務的邏輯都更加清晰、更易了解。就好比我們寫代碼,将一個幾百行的複雜函數重構成若幹個簡單函數,代碼可讀性就會直線上升。另一方面,一些通用的微服務可以被高度複用,無需重複開發和維護,比如你在開發一個電商 APP,可以直接調用第三方提供的支付、物流等服務接口,整體開發和維護效率将大幅提升。

雖然分布式系統與微服務具有非常顯著優勢,但凡事有利必有弊,它們在有效解決原有問題基礎上,也為系統開發和運維帶來了新挑戰,主要包括以下幾點:

  • 模糊性

随着系統的分布式程度越來越高,異常表象與根因之間的邏輯聯系變得愈加模糊,問題診斷的難度急劇上升。比如 A、B 兩個服務共享同一個資料庫執行個體,當 A 服務在壓測期間,大量占用資料庫的服務端連接配接和計算資源,會導緻 B 服務出現連接配接逾時或響應變慢等問題。如果 B 服務是通過 C 服務間接依賴該資料庫執行個體,問題的定位就會變得更加困難。

  • 不一緻

雖然分布式應用從總體上變的更加可靠,但是每一個獨立節點的狀态卻難以保證。導緻這種不一緻的原因有很多,比如前文提到的單機故障這種預期外的不一緻,或者應用 Owner 執行分批釋出或流量灰階時導緻的預期内行為不一緻。這種不一緻性導緻我們難以确定一個使用者請求在系統内的準确執行路徑與行為邏輯,可能引發不可預知的邏輯災難。

  • 去中心化

當你的系統擁有上千個微服務鏡像運作在數百台機器執行個體上,你該如何梳理它們之間的依賴關系,又該如何找到核心業務的關鍵執行路徑?特别是在分布式的場景下,你沒有一個中心化的節點(Master)來儲存每個服務之間的依賴與排程狀态,每個獨立節點都在自行其是,無法分辨自己在整個系統中的位置,隻能“盲人摸象、管中窺豹”,缺乏全局視圖。

分布式系統與微服務帶來的新挑戰無疑讓人頭痛,但也帶來了新技術的發展契機,科技的發展總是這樣循環往複,螺旋式上升。它們帶來的新問題,促使了分布式鍊路追蹤的誕生,使你能夠有效的觀察全局,追蹤流量。我們将在下個章節了解分布式鍊路追蹤的誕生曆程與核心理念。

二、分布式鍊路追蹤的誕生

為了應對分布式環境下的不一緻、模糊性等前文提到的各類問題問題,人們試圖通過請求粒度的軌迹追蹤與資料透傳,實作節點間的确定性關聯,分布式鍊路追蹤技術也由此誕生。

裡程碑事件:Google Dapper

分布式鍊路追蹤誕生的标志性事件就是 Google Dapper 論文的發表。2010 年 4 月,Benjamin H. Sigelman 等人在 Google Technical Report 上發表了《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,揭開了分布式鍊路追蹤的技術大幕,開啟了一段全新技術浪潮。

Dapper 首先明确了分布式鍊路追蹤的兩個目标:任意部署和持續監測。進而給出了三個具體的設計準則:

  • 低開銷:確定核心系統不會因為額外的性能開銷拒絕使用。
  • 應用級透明:對應用開發透明,無需開發人員的協助,降低接入門檻,提高疊代效率。
  • 可擴充:在未來相當長一段時間内,随着業務的高速發展,仍然可以有效運轉。

下面幾張圖展示了 Dapper 對鍊路透傳、調用鍊結構和資料采集流程的描述,我們将在後續章節詳細展開介紹,對 Dapper 感興趣的同學建議直接閱讀原作。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

Dapper 論文有兩個重要的意義,一是詳細闡述了分布式鍊路追蹤的設計理念,為後來的實作者提供了重要的理論指導;二是通過 Dapper 在 Google 生産環境的大規模落地實踐,證明了分布式鍊路追蹤技術的企業級價值,為分布式鍊路追蹤的推廣作出了不可磨滅的貢獻。

基本原理

分布式鍊路追蹤并不是無中生有、憑空誕生的新概念,而是軌迹追蹤在 IT 領域的又一次成功運用。軌迹追蹤理念早已被廣泛應用于社會生活方方面面,比如物流訂單追蹤。一個快遞包裹在發件站被賦予快遞單号,沿途中轉節點會記錄該快遞到達時間等資訊,而使用者通過快遞單号就可以查詢自己的包裹途經了哪些站點,耗時多久,是否存在滞留或丢件情況。下表對比了物流追蹤與鍊路追蹤的關聯與差異性,以便大家了解。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

分布式鍊路追蹤的基本原理就是在分布式應用的接口方法上設定一些觀察點(類似快遞中轉站記錄點),然後在入口節點給每個請求配置設定一個全局唯一的辨別 TraceId(類似快遞單号),當請求流經這些觀察點時就會記錄一行對應的鍊路日志(包含鍊路唯一辨別,接口名稱,時間戳,主機資訊等)。最後通過 TraceId 将一次請求的所有鍊路日志進行組裝,就可以還原出該次請求的鍊路軌迹,如下圖所示。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

分布式鍊路追蹤實作請求回溯的關鍵點有兩個:一是低成本、高品質的觀察點設定,也就是鍊路插樁,確定我們追蹤的資訊足夠豐富,能夠快速定位異常根因;二是保證鍊路上下文在不同環境下都能夠完整透傳,避免出現上下文丢失導緻的斷鍊現象。關于鍊路插樁和上下文透傳的具體内容我們将在實戰篇進行詳細介紹。下面,我們來看一個高速公路例子,進一步加深對鍊路追蹤實作原理的認識。

一輛汽車飛馳在高速公路上

小明、小紅、小玉計劃在“五一”期間去自駕遊,他們的旅遊路線各不相同。如果我們想追蹤他們的行程軌迹與時間該如何實作?

可能你會建議在每輛車上安裝一個追蹤器。确實,這是一種行之有效的方法。但當出行車輛擴充到全國數以十億計的規模,安裝追蹤器成本就會很高。此時我們換個角度思考,高速公路的路線是固定的,每隔一段距離就會有一個收費站,如果我們在每個收費站上安裝監控,記錄車輛在每個收費站的軌迹與時間,就可以很經濟的實作車輛軌迹與行駛時間的追蹤。最終,我們得到了如下行程記錄:

遊客 行程路線 行駛距離 行駛時間
小明 北京 -> 石家莊 -> 鄭州 -> 西安 1140 公裡 13 小時 34 分鐘
小紅 北京 -> 天津 -> 濟南 -> 南京 -> 杭州 1280 公裡 14 小時 33 分鐘
小玉 北京 -> 天津 -> 濟南 -> 南京 -> 上海 1234 公裡 13 小時 53 分鐘
基礎篇丨鍊路追蹤(Tracing)其實很簡單

如果我們将每個遊客替換為服務請求,收費站替換為服務接口,那我們就可以得到每次請求在分布式系統中的調用軌迹與狀态,這就是分布式鍊路追蹤的含義。

基礎術語

雖然分布式鍊路追蹤的實作方式多種多樣,不同開源或商業化産品都有自己的資料模型和定義。但是仍然有一些基礎術語在業界具備廣泛的共識,以 OpenTracing 為例。

Trace

一條 Trace 代表一次入口請求在 IT 系統内的完整調用軌迹及其關聯資料集合。其中,全局唯一的鍊路辨別 TraceId,是最具代表的一個屬性。通過 TraceId 我們才能将同一個請求分散在不同節點的鍊路資料準确的關聯起來,實作請求粒度的“确定性關聯”價值。這也是 Trace 差別于 Metrics、Log 其他兩類可觀測技術的關鍵屬性。

Span

光有 TraceId 還不夠,請求在每一跳的接口方法上執行了什麼動作,耗時多久,執行狀态是成功還是失敗?承載這些資訊的基礎對象就是 Span。通常一個完整的 Span 具有如下屬性:

  • Operation Name:描述了目前接口的行為語義,比如 /api/createOrder 代表執行了一次建立訂單的動作。
  • SpanId/ParentSpanId:接口調用的層級辨別,用于還原 Trace 内部的層次調用關系。
  • Start/FinishTime:接口調用的開始和結束時間,二者相減就是該次調用的耗時。
  • StatusCode:響應狀态,辨別當次調用是成功或失敗。
  • Tags & Events:調用附加資訊,詳見下面的描述。

Tags

SpanName 的描述通常是高度抽象的,僅僅回答這個接口是做什麼的。如果需要進一步記錄請求的行為特征,可以使用 Tags 來擴充語義。Tags 是一組由 {Key:Value} 組成的鍵值對集合,描述這一次接口調用的具體屬性,比如将 UserType 添加到 Tags 中,就可以觀察某一類使用者(比如 VIP 使用者)的鍊路行為狀态。如果将裝置類型加到 Tags 中,可以對比不同裝置的性能差異。

由于 Tags 隻支援結構化的 KV 鍵值對,是以,它可以作為标簽添加到聚合後的鍊路名額中,有效提升監控告警的資料精度。更準确的回答異常或性能問題發生的原因,比如集中在某個地域、裝置或版本。

Logs

Tags 會随着鍊路上下文自動向下遊透傳,如果希望記錄一些不需要透傳的事件資訊,可以使用 Logs 字段。每個 Span 都可以進行多次 Logs 操作,但每個 Logs 對象都需要帶有一個時間戳,Logs 的内容可以是非結構化的複雜對象。為了節省成本,一般不會對 Logs 字段建立索引,也不支援 Logs 的查詢或統計,僅僅作為附加資訊關聯在調用鍊上,用于單請求診斷。

下圖展示了一個 OpenTracing 的 Span 示例,不同開源實作的鍊路模型我們将在後續章節再展開介紹。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

分布式鍊路追蹤已經被廣泛應用于中大型企業的 IT 運維領域,為分布式應用的性能診斷與穩定性保障提供了有效的幫助。此外,分布式鍊路追蹤的開源和商業化生态也發展迅猛,大量獨立服務商或雲廠商紛紛跟進,共同推動了分布式鍊路追蹤技術的崛起。

三、分布式鍊路追蹤的應用

狹義上分布式鍊路追蹤(Tracing)是指跟蹤請求在分布式系統中的流轉路徑與狀态,主要用途是協助開發運維人員進行故障診斷、容量預估、性能瓶頸分析與調用鍊路梳理等工作。技術實作上包含了資料埋點、采集、存儲、分析、可視化等環節,形成了一套完整的技術體系。

而更廣義的分布式鍊路追蹤,則涵蓋了由資料透傳能力衍生的生态系統,比如全鍊路壓測、微服務流量路由、業務場景鍊路拆分等。我們可以為調用鍊路賦予業務語義,也可以将一次調用生命周期内的所有資料進行關聯整合,不再局限于鍊路資料本身。

由此可見,分布式鍊路追蹤的應用場景廣闊,潛力巨大,它的核心屬性就是“關聯”。然而,分布式鍊路追蹤(Tracing)相對于統計名額(Metrics)和應用日志(Logging)來說更加難以了解,不容易運用,更難用好。接下來,我們通過一個生動形象的例子,了解下分布式鍊路追蹤的經典用法,加深對它的技術本質的掌握。

遊客、收費站和交通局

分布式鍊路追蹤的用法有很多,但最經典、最常用的有三種,還是以上一節的高速公路為例,不同角色對應着不同的用法。

  • 遊客,隻關心自身的行程路線,需要途經哪些收費站點?行駛時間有多長?沿途是否有擁堵或危險路段等。
  • 收費站,隻關心自身站點的狀态,比如站點吞吐量、平均過閘時間等,以便于提前安排檢票口值班人數。
  • 交通局,會将所有的出行記錄彙總,提前估算整個高速公路網的出行流量、易擁堵路段、事故多發路段等,以便于提前疏通或加強問題路段,并給出合理的建議出行路線,有時還需要提前制定車輛限流政策等。

分布式鍊路追蹤的應用和行程軌迹追蹤類似,遊客關心的是單次請求的軌迹回溯,收費站關注的是服務接口次元的彙總統計,旅遊局則類似全局鍊路拓撲梳理。

單請求軌迹回溯

單請求軌迹回溯是分布式鍊路追蹤最基礎的功能,它記錄了一次請求經過的所有服務節點以及對應的節點狀态資訊(接口名稱、耗時、狀态碼等),這就好比記錄了遊客自駕遊時經過的所有收費站,以及沿途的路況與行駛時間等資訊。單請求軌迹回溯是診斷特定請求異常/逾時原因的有效手段,可以快速定位異常節點(擁堵的收費站)。

比較成熟的 Tracing 産品(比如阿裡雲的應用實時監控服務 ARMS)除了基礎的鍊路資料外,還會記錄請求出入參、本地方法棧、關聯 SQL 與異常堆棧等資訊。這些細節資訊就好比車輛的型号大小、駕駛員駕齡、是否醉酒、沿途每一路段的詳細路況等,當調用不符合預期(行程異常)時,就可以精準的定位根因,如下圖所示:

ARMS:

https://help.aliyun.com/document_detail/64995.html

基礎篇丨鍊路追蹤(Tracing)其實很簡單

服務監控

假如你是收費站的站長,你會關注哪些資訊?收費站的車輛吞吐量?平均的過閘時間?車輛的來源與去向?同理,每一個服務節點,将途經的所有調用資訊彙總後,就可以得到目前服務接口的吞吐量、耗時、來源與去向等統計名額。這些名額可以幫助我們快速識别目前服務的健康狀态。在實際生産系統中,還可以與告警系統結合,實作風險的快速識别與處理,降低業務損失。

基礎篇丨鍊路追蹤(Tracing)其實很簡單

鍊路拓撲

假如你是交通局的局長,你可能會關注全國高速公路網的整體運作狀态,有哪些易擁堵或事故多發路段與站點,如何確定春運高峰期核心路段運作通暢,不會出現重大交通癱瘓事件等等。此時,你需要對所有的車輛行程軌迹進行彙總分析。

同理,鍊路拓撲就是将全局或某一入口服務的所有調用鍊路進行彙總,聚合為鍊路拓撲大圖,進而分析目前鍊路的性能瓶頸點、易故障點等,提前進行性能優化或風險防控,還可以根據曆史流量來指導未來(比如雙 11 大促)的容量評估。

剩餘60%,完整内容請點選下方連結檢視:

https://developer.aliyun.com/article/1179526?utm_content=g_1000369774

版權聲明:本文内容由阿裡雲實名注冊使用者自發貢獻,版權歸原作者所有,阿裡雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿裡雲開發者社群使用者服務協定》和《阿裡雲開發者社群知識産權保護指引》。如果您發現本社群中有涉嫌抄襲的内容,填寫侵權投訴表單進行舉報,一經查實,本社群将立刻删除涉嫌侵權内容。

繼續閱讀