微服務的戰爭:選型?分布式鏈路追蹤
本文轉載自微信公眾號「腦子進煎魚了」,作者陳煎魚 。轉載本文請聯系腦子進煎魚了公眾號。
“微服務的戰爭” 是一個關于微服務設計思考的系列題材,主要是針對在微服務化后所出現的一些矛盾/沖突點,不涉及具體某一個知識點深入。如果你有任何問題或建議,歡迎隨時交流。
背景
在經歷微服務的戰爭:級聯故障和雪崩 的 P0 級別事件后,你小手一攤便葛優躺了。開始進行自我復盤,想起這次排查經歷,由于現在什么基礎設施都還沒有,因此在接收到客戶反饋后,你是通過錯誤日志進行問題檢查的。
但在級聯錯誤中,錯誤日志產生的實在是太多了,不同的服務不同的鏈路幾乎都擠在一起,修復時間都主要用在了翻日志上,翻了好幾頁才找到了相對有效的錯誤信息。
如果下一次在出現類似的問題,可不得了,MTTR 太久了,4 個 9 很快就會用完。這時候你想到了業界里經常被提起的一個利器,那就是 “分布式鏈路追蹤系統”。粗略來講,能夠看到各種應用的調用依賴:
其中最著名的是 Google Dapper 論文所介紹的 Dapper。源于 Google 為了解決可能由不同團隊,不同語言,不同模塊,部署在不同服務器,不同數據中心的所帶來的軟件復雜性(很難去分析,無法做定位),構建了一個的分布式跟蹤系統:
自此就開啟了業界在分布式鏈路的啟發/啟蒙之路,很多現在出名的分布式鏈路追蹤系統都是基于 Google Dapper 論文發展而來,基本原理和架構都大同小異。若對此有興趣的可具體查看 Google Dapper,非常有意思。
(Google Dapper 中存在跟蹤樹和 Span 的概念)
選型?有哪些
想做鏈路追蹤,那必然要挑選一款開源產品作為你的分布式鏈路追蹤系統,不大可能再造一個全新的,先實現業務目的最重要。因此在網上一搜,發現如下大量產品:
- Twitter:Zipkin。
- Uber:Jaeger。
- Elastic Stack:Elastic APM。
- Apache:SkyWalking(國內開源愛好者吳晟開源)。
- Naver:Pinpoint(韓國公司開發)。
- 阿里:鷹眼。
- 大眾點評:Cat。
- 京東:Hydra。
隨手一搜就發現這類產品特別的多,并且據聞各大公司都有自己的一套內部鏈路追蹤系統,這下你可犯了大難。他們之間都是基于 Google Dapper 演進出來的,那本質上到底有什么區別,怎么延伸出這么多的新產品?
Jaeger
首先看看由 Uber 開發的 Jaeger,Jaeger 目前由 Cloud Native Computing Foundation(CNCF)托管,是 CNCF 的第七個頂級項目(于 2019 年 10 月畢業):
- Jaeger Client:Jaeger 客戶端,是 Jaeger 針對 OpenTracing API 的特定語言實現,可用于手動或通過與 OpenTracing 集成的各種現有開源框架(例如Flask,Dropwizard,gRPC等)來檢測應用程序以進行分布式跟蹤。
- Jaeger Agent:Jaeger 客戶端代理,在 UDP 端口上監聽所接受的跨度并將其分批發送給 Collector。
- Jaeger Collector:Jaeger 收集器,顧名思義是面向 Agent,用于收集/管理鏈路的追蹤信息。
- Jaeger Query:數據查詢與前端界面展示。
- Jaeger Ingester:可從 Kafka 讀取數據并寫入其他的存儲介質(Cassandra,Elasticsearch)。
在了解 Jaeger 的各組件功能后,主要關注其整體的整體架構上的數據流轉:
Jaeger 是一個很經典的架構,由客戶端主動發送鏈路信息到 Agent,Agent 上報給 Collector,再經由隊列,最終落地到存儲。再由另外的可視化管理后臺進行查看和分析。
更具現化就是 上報 =》收集 =》存儲 =》分析的標準化流程。并且你會發現 Jaeger 與 Zipkin 在架構上差不多:
- Zipkin Collector:Zipkin 收集器,用于收集/管理鏈路的追蹤信息。
- Storage:Zipkin 數據存儲,支持 Cassandra、ElasticSearch 和 MySQL 等第三方存儲。
- Zipkin Query Service:數據存儲并建立索引后,用于查找和檢索跟蹤信息。
- Web UI:數據查詢與前端界面展示。
從時間上來看 Jaeger 比 Zipkin 晚四年,莫非是重復造輪子。經過翻閱,可得知做 Jaeger 的主要原因是:
當時將跨度發送到 Zipkin 的唯一方法是通過 Scribe,而 Zipkin 支持的唯一高性能數據存儲是 Cassandra。當時 Uber 對這兩種技術都沒有經驗,因此選擇了自己構建一個后端,該后端將一些自定義組件與 Zipkin UI 結合在一起,形成了一個完整的跟蹤系統。
更詳細可閱讀 Evolving Distributed Tracing at Uber Engineering,可以了解很多細節。
阿里鷹眼
鏈路追蹤系統的另一代表,基于日志和流式計算去做的居多,像是阿里的鷹眼,滴滴的 traces,如下圖:
更具體可見《阿里巴巴鷹眼技術解密》 和 《異構系統鏈路追蹤——滴滴 trace 實踐》 在大會上的分享,這里就不再贅述了,推薦好奇或憂愁鏈路追蹤落地的小伙伴們閱讀。
總結
大多數在初始選型時都會選擇親和性比較強的追蹤系統,就像是 Jaeger 屬于 Go,Zipkin、Skywalking 是 Java 系居多,三者都完全兼容 OpenTracing,只是架構上多少有些不同,且都是基于 Google Dapper 發散,因此所支持的基本功能和查詢頁面優雅與否很重要。
而本來就有原始的 N 個系統,如果想接入直接新的鏈路追蹤系統,還是非常麻煩的。因為原意想接入,必然是想解決原有系統的排查/定位問題,而不單單是為了新系統,因此單從接入的角度來講,大多不會就不會使用既有開源追蹤系統(除非歷史債務不大),且數據量可能極大。
因此基于既有方法去改造來清洗數據再做成鏈路追蹤的模式也挺常見的,這之中日志常常是一個比較好的下手點,也就是去清洗某某數據,形成新的分析系統,再造一個內部輪子。
另外近兩年基于 ServiceMesh 的 ”無” 侵入式鏈路追蹤也廣受歡迎,似乎是一個被看好的方向,其代表作之一 Istio 便是使用 CNCF 出身的 Jaeger,且 Jaeger 還兼容 Zipkin,在這點上 Jaeger 完勝。