作者|涯海
全鏈路追蹤的價值
鏈路追蹤的價值在於“關聯”,終端用戶、后端應用、雲端組件(數據庫、消息等)共同構成了鏈路追蹤的軌跡拓撲大圖。這張拓撲覆蓋的范圍越廣,鏈路追蹤能夠發揮的價值就越大。而全鏈路追蹤就是覆蓋全部關聯 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/document_detail/106086.html?spm=ata.21736010.0.0.5d3a7f117o1Lty
2、 前后端鏈路關聯文檔:https://help.aliyun.com/document_detail/91409.html#title-6rx-0lb-p1o
3、ARMS 應用監控官網文檔:https://help.aliyun.com/document_detail/97924.html
4、ARMS 應用監控官網文檔:https://help.aliyun.com/document_detail/118912.html
5、ARMS 控制台:
https://arms.console.aliyun.com/?spm=ata.21736010.0.0.5d3a7f117o1Lty
6、開源自建/托管與商業化自研 Trace,如何選擇?:
https://mp.weixin.qq.com/s?spm=a2c6h.12873639.0.0.2ff66234Viwi2h&__biz=MzIzOTU0NTQ0MA==&mid=2247504737&idx=1&sn=2de2fb0e0656c702fa4d2546a9cdd2e5&scene=21#wechat_redirect
點擊下方鏈接,立即體驗鏈路追蹤!
https://www.aliyun.com/product/xtrace?spm=5176.8140086.J_8058803260.58.4da02c90QhBtVo
快速分析和診斷分布式應用架構下的性能瓶頸,提高微服務時代下的開發診斷效率。