作者|涯海
全鏈路追蹤的價值
鏈路追蹤的價值在於“關聯”,終端使用者、後端應用、雲端元件(資料庫、訊息等)共同構成了鏈路追蹤的軌跡拓撲大圖。這張拓撲覆蓋的範圍越廣,鏈路追蹤能夠發揮的價值就越大。而全鏈路追蹤就是覆蓋全部關聯 IT 系統,能夠完整記錄使用者行為在系統間呼叫路徑與狀態的最佳實踐方案。
完整的全鏈路追蹤可以為業務帶來三大核心價值:端到端問題診斷,系統間依賴梳理,自定義標記透傳。
• 端到端問題診斷:VIP 客戶下單失敗,內測使用者請求超時,許多終端使用者的體驗問題,追根溯源就是由於後端應用或雲端元件異常導致的。而全鏈路追蹤是解決端到端問題最有效的手段,沒有之一。
• 系統間依賴梳理:新業務上線,老業務裁撤,機房搬遷/架構升級,IT 系統間的依賴關係錯綜複雜,已經超出了人工梳理的能力範疇,基於全鏈路追蹤的拓撲發現,使得上述場景決策更加敏捷、可信。
• 自定義標記透傳:全鏈路壓測,使用者級灰度,訂單追溯,流量隔離。基於自定義標記的分級處理&資料關聯,已經衍生出了一個繁榮的全鏈路生態。然而,一旦發生資料斷鏈、標記丟失,也將引發不可預知的邏輯災難。
全鏈路追蹤的挑戰與方案
全鏈路追蹤的價值與覆蓋的範圍成正比,它的挑戰也同樣如此。為了最大程度地確保鏈路完整性,無論是前端應用還是雲端元件,無論是 Java 語言還是 Go 語言,無論是公有云還是自建機房,都需要遵循同一套鏈路規範,並實現資料互聯互通。多語言協議棧統一、前/後/雲(多)端聯動、跨雲資料融合是實現全鏈路追蹤的三大挑戰,如下圖所示:
1、多語言協議棧統一
在雲原生時代,多語言應用架構越來越普遍,利用不同語言特性,實現最佳的效能和研發體驗成為一種趨勢。但是,不同語言的成熟度差異,使得全鏈路追蹤無法做到完全的能力一致。目前業界的主流做法是,先保證遠端呼叫協議層格式統一,多語言應用內部自行實現呼叫攔截與上下文透傳,這樣可以確保基礎的鏈路資料完整。
但是,絕大部分線上問題無法僅通過鏈路追蹤的基礎能力就能夠有效定位並解決,線上系統的複雜性決定了一款優秀的 Trace 產品必須提供更加全面、有效的資料診斷能力,比如程式碼級診斷、記憶體分析、執行緒池分析、無損統計等等。充分利用不同語言提供的診斷介面,最大化的釋放多語言產品能力是 Trace 能夠不斷向前發展的基礎。
- 透傳協議標準化:全鏈路所有應用需要遵循同一套協議透傳標準,保證鏈路上下文在不同語言應用間能夠完整透傳,不會出現斷鏈或上下文缺失的問題。目前主流的開源透傳協議包括 Jaeger、SkyWalking、ZipKin 等。
- 最大化釋放多語言產品能力:鏈路追蹤除了最基礎的呼叫鏈功能外,逐步衍生出了應用/服務監控,方法棧追蹤,效能剖析等高階能力。但是不同語言的成熟度導致產品能力差異較大,比如 Java 探針可以基於 JVMTI 實現很多高階的邊緣側診斷。優秀的全鏈路追蹤方案會最大化的釋放每種語言的差異化技術紅利,而不是一味的追求趨同平庸。感興趣的同學可以閱讀文章《開源自建/託管與商業化自研 Trace,如何選擇》。
2、前後雲(多)端聯動
目前開源的鏈路追蹤實現主要集中於後端業務應用層,在使用者終端和雲端元件(如雲資料庫)側缺乏有效的埋點手段。主要原因是後兩者通常由雲服務商或三方廠商提供服務,依賴於廠商對於開源的相容適配性是否友好。而業務方很難直接介入開發。
上述情況的直接影響是前端頁面響應慢,很難直接定位到後端哪個應用或服務導致的,無法明確給出確定性的根因。同理,雲端元件的異常也難以直接與業務應用異常劃等號,特別是多個應用共享同一個資料庫例項等場景下,需要更加迂迴的手段進行驗證,排查效率十分低下。
為了解決此類問題,首先需要雲服務商更好的支援開源鏈路標準,新增核心方法埋點,並支援開源協議棧透傳與資料迴流(如阿里雲 ARMS 前端監控支援 Jaeger 協議透傳與方法棧追蹤)。
其次,由於不同系統可能因為歸屬等問題,無法完成全鏈路協議棧統一,為了實現多端聯動,需要由 Trace 系統提供異構協議棧的打通方案。
異構協議棧打通
為了實現異構協議棧(Jaeger、SkyWalking、Zipkin)的打通,Trace 系統需要支援兩項能力:一是協議棧轉換與動態配置,比如前端向下透傳了 Jaeger 協議,新接入的下游外部系統使用的則是 ZipKin B3 協議。在兩者之間的 Node.js 應用可以接收 Jaeger 協議並向下透傳 ZipKin 協議,保證全鏈路標記透傳完整性。二是服務端資料格式轉換,可以將上報的不同資料格式轉換成統一格式進行儲存,或者在查詢側進行相容。前者維護成本相對較小,後者相容性成本更高,但相對更靈活。
3、跨雲資料融合
很多大型企業,出於穩定性或資料安全等因素考慮,選擇了多雲部署,比如國內系統部署在阿里雲,海外系統部署在 AWS 雲,涉及企業內部敏感資料的系統部署在自建機房等。多雲部署已經成為了一種典型的雲上部署架構,但是不同環境的網路隔離,以及基礎設施的差異性,也為運維人員帶來了巨大的挑戰。
由於雲環境間僅能通過公網通訊,為了實現多雲部署架構下的鏈路完整性,可以採用鏈路資料跨雲上報、跨雲查詢等方式。無論哪種方式,目標都是實現多雲資料統一可見,通過完整鏈路資料快速定位或分析問題。
跨雲上報
鏈路資料跨雲上報的實現難度相對較低,便於維護管理,是目前雲廠商採用的主流做法,比如阿里雲 ARMS 就是通過跨雲資料上報實現的多雲資料融合。
跨雲上報的優點是部署成本低,一套服務端便於維護;缺點是跨雲傳輸會佔用公網頻寬,公網流量費用和穩定性是重要限制條件。跨雲上報比較適合一主多從架構,絕大部分節點部署在一個雲環境內,其他雲/自建機房僅佔少量業務流量,比如某企業 toC 業務部署在阿x雲,企業內部應用部署在自建機房,就比較適合跨雲上報的方式,如下圖所示。
跨雲查詢
跨雲查詢是指原始鏈路資料儲存在當前雲網路內,將一次使用者查詢分別下發,再將查詢結果聚合進行統一處理,減少公網傳輸成本。
跨雲查詢的優點就是跨網傳輸資料量小,特別是鏈路資料的實際查詢量通常不到原始資料量的萬分之一,可以極大地節省公網頻寬。缺點是需要部署多個資料處理終端,不支援分位數、全域性 TopN 等複雜計算。比較適合多主架構,簡單的鏈路拼接、max/min/avg 統計都可以支援。
跨雲查詢實現有兩種模式,一種是在雲網路內部搭建一套集中式的資料處理終端,並通過內網專線打通使用者網路,可以同時處理多個使用者的資料;另一種是為每個使用者單獨搭建一套 VPC 內的資料處理終端。前者維護成本低,容量彈性更大;後者資料隔離性更好。
其他方式
除了上述兩種方案,在實際應用中還可以採用混合模式或僅透傳模式。
混合模式是指將統計資料通過公網統一上報,進行集中處理(資料量小,精度要求高),而鏈路資料採用跨雲查詢方式進行檢索(資料量大,查詢頻率低)。
僅透傳模式是指每個雲環境之間僅保證鏈路上下文能夠完整透傳,鏈路資料的儲存與查詢獨立實現。這種模式的好處就是實現成本極低,每朵雲之間僅需要遵循同一套透傳協議,具體的實現方案可以完全獨立。通過同一個 TraceId 或應用名進行人工串聯,比較適合存量系統的快速融合,改造成本最小。
全鏈路追蹤接入實踐
前文詳細介紹了全鏈路追蹤在各種場景下面臨的挑戰與應對方案,接下來以阿里雲 ARMS 為例,介紹一下如何從 0 到 1 構建一套貫穿前端、閘道器、服務端、容器和雲元件的完整可觀測系統。
- Header 透傳格式:統一採用 Jaeger 格式,Key 為 uber-trace-id, Value 為 {trace-id}:{span-id}:{parent-span-id}:{flags} 。
- 前端接入:可以採用 CDN(Script 注入)或 NPM 兩種低程式碼接入方式,支援 Web/H5、Weex 和各類小程式場景。
- 後端接入:
- Java 應用推薦優先使用 ARMS Agent,無侵入式埋點無需程式碼改造,支援邊緣診斷、無損統計、精準取樣等高階功能。使用者自定義方法可以通過 OpenTelemetry SDK 主動埋點。
- 非 Java 應用推薦通過 Jaeger 接入,並將資料上報至 ARMS Endpoint,ARMS 會相容多語言應用間的鏈路透傳與展示。
阿里雲 ARMS 目前的全鏈路追蹤方案是基於 Jaeger 協議,正在開發 SkyWalking 協議,以便支援 SkyWalking 自建使用者的無損遷移。前端、Java 應用與非 Java 應用全鏈路追蹤的呼叫鏈效果如下圖所示:
1、前端接入實踐
ARMS 前端監控支援 Web/H5、Weex、支付寶和微信小程式等,本文以 Web 應用通過 CDN 方式接入 ARMS 前端監控為例,簡要說明接入流程,詳細接入指南參考 ARMS 前端監控官網文件。
- 登入 ARMS 控制檯,在左側導航欄中單擊接入中心,點選選擇前端 Web/H5 接入。
- 輸入應用名稱,點選建立;勾選SDK擴充套件配置項區域需要的選項,快捷生成待插入頁面的BI探針程式碼。
- 選擇非同步載入,複製下面程式碼並貼上至頁面HTML中 元素內部的第一行,然後重啟應用。
<script>
!(function(c,b,d,a){c[a]||(c[a]={});c[a].config={pid:"xxx",imgUrl:"https://arms-retcode.aliyuncs.com/r.png?",
enableLinkTrace: true, linkType: 'tracing'};
with(b)with(body)with(insertBefore(createElement("script"),firstChild))setAttribute("crossorigin","",src=d)
})(window,document,"https://retcode.alicdn.com/retcode/bl.js","__bl");
</script>
為了實現前後端鏈路打通,上述探針程式碼中必須包含以下兩個引數:
- enableLinkTrace:true // 表示開啟前端鏈路追蹤功能
- linkType: 'tracing' // 表示生成 Jaeger 協議格式的鏈路資料,Hearder 允許 uber-trace-id 透傳
另外,如果 API 與當前應用非同源,還需要新增 enableApiCors: true 這個引數,並且後端伺服器也需要支援跨域請求及自定義header 值,詳情參考前後端鏈路關聯文件。如需驗證前後端鏈路追蹤配置是否生效,可以開啟控制檯檢視對應 API 請求的 Request Headers 中是否有 uber-trace-id 這個標識。
2、Java 應用接入實踐
Java 應用推薦接入 ARMS JavaAgent,無侵入式探針開箱即用,無需修改業務程式碼,詳細接入指南參考 ARMS 應用監控官網文件。
- 登入 ARMS 控制檯,在左側導航欄中單擊接入中心,點選選擇後端 Java 接入。
- 根據需要選擇手動安裝、指令碼安裝和容器服務安裝任意方式。
- 根據操作指南確保探針下載並解壓至本地,正確配置 appName、LicenseKey 和 javaagent 啟動引數後,重啟應用。
3、非 Java 應用接入實踐
非 Java 應用可以通過開源 SDK(比如 Jaeger)將資料上報至 ARMS 接入點,詳細接入指南參考 ARMS 應用監控官網文件。
- 登入 ARMS 控制檯,在左側導航欄中單擊接入中心,點選選擇後端 Go/C++/.NET/Node.js 等接入方式。
- 根據操作指南替換接入點 ,配置完成後重啟應用。
全鏈路追蹤只是開始,不是結束
從 2010 年穀歌發表 Dapper 論文開始,鏈路追蹤已經發展了十多年。但是關於鏈路追蹤的書籍或深度文章一直都比較少,大部分部落格只是簡單介紹一些開源的概念或 QuickStart,一個大型企業如何建設一套真正可用、好用、易用的鏈路追蹤系統,需要填哪些坑,避哪些雷,很難找到比較系統、全面的答案。
全鏈路追蹤接入只是 Tracing 的起點,選擇適合自身業務架構的方案,可以避免一些彎路。但鏈路追蹤不僅僅只是看看呼叫鏈和服務監控,如何向上賦能業務,衍生至業務可觀測領域輔助業務決策?如何向下與基礎設施可觀測聯動,提前發現資源類風險?後面還有很多的工作要做,期待更多同學一起加入分享。
相關連結:
1、 ARMS 前端監控官網文件:https://help.aliyun.com/docum...
2、 前後端鏈路關聯文件:https://help.aliyun.com/docum...
3、ARMS 應用監控官網文件:https://help.aliyun.com/docum...
4、ARMS 應用監控官網文件:https://help.aliyun.com/docum...
5、ARMS 控制檯:
https://arms.console.aliyun.c...
6、開源自建/託管與商業化自研 Trace,如何選擇?:
https://mp.weixin.qq.com/s?sp...
點選下方連結,立即體驗鏈路追蹤!
https://www.aliyun.com/produc...
快速分析和診斷分散式應用架構下的效能瓶頸,提高微服務時代下的開發診斷效率。