企業如何從 0 到 1 構建整套全鏈路追蹤體系

作者 | 夏明

本文將跟大家分享 ARMS 在全鏈路追蹤領域的最佳實踐。

主要分爲四部分:首先,是對分佈式鏈路追蹤的整體簡介。其次,是對 ARMS 在分佈式鏈路追蹤領域的核心能力進行介紹。然後,介紹如何從 0 到 1 構建整套全鏈路追蹤體系。最後,介紹一些最佳實踐案例。

一、什麼是分佈式鏈路追蹤首先。

什麼是分佈式鏈路追蹤。我對分佈式鏈路追蹤的理解就是跟蹤請求在分佈式系統中的流轉路徑與狀態,從而協助開發人員能夠進行故障診斷、容量評估、性能瓶頸分析等工作。

我們可以看到典型的鏈路軌跡追蹤例子:比如用戶通過手機做了一個下單動作,這個請求會通過移動端來到網關,再到應用層,比如說有交易、下單、支付,等等一系列的應用,然後中間也會穿插到去調用雲基礎設施,這樣用戶的行爲軌跡是能夠被清晰還原出來的。

爲了更方便的理解這個概念,我們可以把鏈路追蹤和物流追蹤做對比。在發送快遞物流時,每個快遞包裹都會賦予一個唯一的快遞單號,對於系統請求來說就是全局唯一的 TraceId。通過快遞單號來查詢快遞途徑哪些站點,是否有延遲或丟件情況。那麼,也同樣可以通過 TraceId 來查詢請求在每個系統之間的流轉路徑和狀態。除了快遞訂單查詢之外,還可以把整個物流狀態,按照站點去進行彙總統計,來看每個站點吞吐,從而進行物流提效的優化工作。對於鏈路追蹤來說也是一樣的,我們可以把鏈路數據進行一個統計,然後去看每一個應用或接口的狀態,或者去梳理它們之間的強弱依賴。那麼,什麼樣的系統更加需要鏈路追蹤呢?當微服務架構拆分的越精細,服務間依賴越複雜的系統,就更加的需要鏈路追蹤技術,比較典型的就是電商這種。

接下來我們看一下鏈路追蹤作爲可觀測的三元組之一,就是 Traces、Metrics 和 Logs。其最大價值就是實現了除機器和時間維度之外的用戶行爲的確定性關聯。怎麼理解這個事情呢?就是在沒有 Tracing 之前,比如說通過指標或者日誌,只能根據數據在同一臺機器上,並且在同一個時間點,判斷它們應該是在一起的。但這只是弱關聯,並不是強關聯。而調用鏈會很明確說明這個請求就是這個數據,就是來到了這個節點,這個信息是一定準確的。通過這種確定性的關聯,除了可以將服務應用接口層面的數據關聯起來之外,還可以通過打標上下文傳遞的方式,把一些業務的標籤,比如說來自於什麼渠道、訂單金額等這種直接、間接的數據都關聯起來,發揮 1+1>N 的價值。

接下來再看一下鏈路追蹤的應用場景,我對它做了一個初步分級。

從下往上看,最基礎級就是通過調用鏈來還原單次請求的軌跡狀態,這是最基本的應用。

再往上,可以對鏈路數據去做預聚合或後聚合統計的分析,去看整個鏈路在概率分佈上的一些信息,比如說整個服務維度的監控數據,上下游整體的依賴,這是第二級——聚合分析。

第三等級,就是除了調用鏈數據本身具備的這些鏈路數據之外,還可以更進一步發揮關聯性作用,把一些間接的業務數據,包括容器或者 JVM 的一些指標信息或者是一些變更的日誌事件,也能夠通過調用鏈緊密的關聯在一起,形成多維數據關聯和分析,最終來實現我們根因定位的能力。

再往後有點像自動駕駛,有了這麼多數據,能不能夠自動發現其中一些問題?可以結合領域專家經驗和恰當的算法,來實現整個診斷流程自動化或者半自動化。

最後一步就是診斷問題的最終目標 -- 保障系統穩定。能不能夠把問題診斷和系統恢復兩個事關聯在一起?從而實現整個系統的故障自愈,進一步提升穩定性。這個就需要與管控系統去融合。目前開源 Tracing 系統大概是在 L1 到 L3 的等級。ARMS 我們那邊沉澱了很多領域專家經驗以及算法可以做到 L4 等級,ARMS 再加上一些應用託管服務進行自動流控降級、彈性擴縮容,把監控和管控系統結合在一起,從而實現故障自愈能力。

接下來我們再看看鏈路追蹤的發展趨勢。在 2010 年,隨着谷歌論文發表,拉開了整個鏈路追蹤的技術序幕,很多廠商都紛紛實現了自己的鏈路追蹤技術。當然,在谷歌之前也有很多其他探索,但谷歌給了後續實現者比較完整的理論基礎。同時,通過自身實踐,證明了鏈路追蹤的企業級價值,這是開山鼻祖式的奠基。

到了 2016 年,因爲之前大家廠商紛紛實現自己的鏈路追蹤,這個標準沒有統一,就爲遷雲、上雲帶來很多問題。因此,開源社區發起了 OpenTracing 項目,定義了相對比較完善標準的鏈路的通用規範,也發展出了類似 Jaeger 這種符合 OpenTracing 規範的開源實現。到了 2019 年,大家考慮到可觀測逐漸向一體化發展,光有 Tracing 也不夠,需要把 Tracing 和指標和日誌能夠關聯在一起,OpenTracing 定義就相對比較狹隘,不能滿足可觀測的需求。所以在 2019 年,就是 OpenTeleMetry,然後提出了這樣的一個開源項目。將 OpenTracing 和 OpenCensus 進行了融合,能夠致力於去解決 Logs 和 Traces、Metrics 三者有機統一。

二、ARMS 的鏈路追蹤到底具備哪些能力

接下來,我們看一下 ARMS 的鏈路追蹤到底具備哪些能力。首先,我把 ARMS 的能力抽象爲四個點:

接下來,我們逐一介紹下這四個方面:

首先就是接入難, ARMS 目前提供了 Java 無侵入的探針技術方式,如果你是 Java 應用就可以很快地接入 ARMS。比如說通過一個 -javaagent 的命令,或者是在 ACK 容器服務環境下,通過一個 Annotation 就可以很快地接入。如果是非 Java 語言,也可以利用開源 SDK 通過修改 Endpoint 快速地接入到 ARMS,從而實現全鏈路追蹤,基本上相當於是開箱即用的。

我們對語言組件的覆蓋也是相對比較齊全的,主流組件基本上都有支持。同時, ARMS 完全兼容開源的 OpenTracing、 OpenTelemetry 等各種開源格式。如已接入,遷移到 ARMS 也是非常的方便。

其次,診斷難。在生產環境去診斷問題時,有時不僅僅需要調用鏈,還需要很多其他的數據一起結合。比如說發現某個應用接口或者是業務出現問題,根據各種各樣條件來去篩選出想要的調用鏈,通過調用鏈來去追溯上下游,看看問題大概瓶頸點在哪裏。如果這個時候出現了比較慢的一些情況,就是接口粒度還不足以定位問題的時候,我們可以通過 ARMS 的線程剖析功能,自動地幫你把慢調用本地完整的方法棧能夠獲取下來,能夠實現代碼級定位。如果是業務上出錯了,還可以跟業務日誌進行關聯綁定,能夠看到每次調用,每筆請求關聯背後業務的行爲和日誌是什麼樣的。如果前面這四步仍然不足以去定位根因,還可以結合內存快照或是線程池分析,常見的就是數據庫連接打滿,或者是線程池打滿等。

除了上面這一整套診斷能力幫助團隊完成定位之外,ARMS 也能夠通過自動診斷能力解決常見問題。比如說我們經常會遇到一些數據庫 MySQL 問題,數據庫 MySQL 有很多原因比方說服務端原因,服務端的連接池打滿,或者是客戶端的連接池打滿,或者是客戶端一次查了特別多數據需要分批等等。面對這些常見的原因,ARMS 都可以自動診斷出來。

解決完診斷難,接下來就是運維難的問題。越是體量越大的公司,這個問題會越嚴重 ARMS 作爲阿里鷹眼的升級,在雙十一場景下結合多年驗證與優化,沉澱了大量經驗,比如說我們的 Agent 是會經過多輪、各種級別的灰度驗證,保證我們客戶端側穩定。服務端也會支持比如說多可用區容災或者是全鏈路端的 SLO 體系建設,還有包括我們多級的客戶支持和 Oncall 應急值班,這些都是可以直接享受到這樣的服務,而不需要重新的去建設這樣的體系。

在大部分場景下,除了穩定性之外,還經常會遇到海量數據場景下查詢性能問題,當數據達到每天幾百 TB,數據存儲和數據查詢的索引可能已失效,無法滿足業務要求。ARMS 沉澱了多種性能加速方案,比如說可以實現最基礎的就是租戶地域隔離,其次數據可以通過應用去做路由存儲,如果應用級還不夠,還可以再繼續根據數據的一些特定的特徵,如 TraceId 或者其他特徵進一步打散,從而提高併發查詢的效率。

第四點就是大家比較關心的成本問題,ARMS 除了自身按需存儲之外,還通過冷熱數據分離和精準採樣方案,進一步降低用戶成本。

比如說我們可以把熱數據,比如說 30 分鐘內數據我們會經常查詢,我們可以把它存在熱存儲裏面,滿足全量的分析的需求。30 分鐘之後的數據進行持久化,比方說 15 天、30 天。這個時候可以僅把其中錯、慢或者滿足一定業務特徵(比如說 VIP 用戶的一些鏈路)存儲下來,這樣整個存儲成本就會比較低,並保持查詢體驗。

當然,在做鏈路採樣時就無可避免的會遇到指標數據不準的情況。ARMS 通過在客戶端完成預聚合,來保證鏈路數據無論怎麼去採樣,即使千分之一,但依舊保證指標數據精準性。

這裏做個簡單對比,如果採用開源方案,最起碼需要存儲以及流計算處理服務器建設,這種 ES 和 ECS 的成本大概 200 元 / 天。但如果直接使用 ARMS 的按量付費,每天大概只需要十幾塊錢。每 GB 成本可能只要 1 毛 9 不到 2 毛錢,遠遠低於開源自建成本。

值得一提的就是,ARMS 進入 Gartner APM 象限,也是國內唯一的雲廠商,Gartner 對 ARMS 的 APM 評價是中國影響力最強,對開源集成性也非常好,成本也是非常大優勢。

三、如何從 0 到 1 建設追蹤體系

介紹完產品核心能力之後,來講講如何從 0 到 1 建設追蹤體系。

我們大概可能需要完成這樣 4 步:

第一步,完成整個應用的全鏈條全鏈路的上下文透傳,從端側設備開始到後端,然後網關或者是應用等等。這裏面的話其實就涉及到異構語言的數據打通和前後端的透傳,這一套方案 ARMS 是都已實現了。

第二步,完成了客戶端的這種全鏈路埋點之後,我們數據要上報上來,就會面臨存儲和計算的成本,最好的方式就是說能夠按需去存儲數據,只存有價值的數據來降低成本。

第三步就是數據存儲下來之後,肯定還要通過查詢再發揮它的價值。這時候遇到的問題就是數據之間的格式不統一,能不能把所有的指標數據轉化成一個比方說 Prometheus 的這種格式,這樣指標數據格式相對統一了,Traces 能不能支持這種 OpenTelemetry 的格式,然後是日誌支持 Loki 這種方案。

如果數據格式跟開源保持統一再去做第 4 步,釋放價值就會比較容易。除了產品提供的預置大盤之外,還可以靈活自定義用戶檔案。當然還可以按照用戶的使用習慣,也可以做一些自定義的控制檯。同樣道理,告警也是一樣的,我們可以去用 PromQL 做一個靈活的自定義的告警,同時我們也支持把數據路由到用戶名下的一些存儲,比如說 SLS 下面,這樣你想去做一些二次的批量的分析,這些都可以支持。這就是我們從 0 到 1 去建設鏈路追蹤體系的大概步驟。

接下來,每個步驟都單獨來看。第一步,就是要完成異構應用的全鏈路的追蹤,比如說前端或者說整個透傳的格式,或需要採用統一格式,比如說我們可以選擇統一的 Jaeger 格式來透傳來我們的協議頭,我們前端接入比如說我們可以採用 CDN 或者 NPM 兩種的這種低代碼的接入方式,可以支持外部小程序等各種各樣的場景,我們後端如果是 JAVA 的話,就會優先推進使用 ARMS Agent 來完成無侵入的這樣的一個代碼的接入。並且在 JAVA 的應用上面,我們會提供很多比如說邊緣診斷、無損統計的這樣一些高階的能力,非 JAVA 的話就可以比方說我們可以通過開源的 Agent 和 SDK 來接入,然後並且上報到我們的 Endpoint 上面,當然 ARMS 也在去兼容 SkyWalking 的協議格式。

第二步,正如剛纔所講,數據打通之後,需要去進行精準採樣和冷熱存儲分離。但是對於使用者來說,需要去定義我們尾部採樣策略,比如說默認的除了錯慢全採之外,有沒有需要根據業務特徵進行採樣,或者是按需的去調整數據存儲週期。

第三步,就是需要去自定義監控大盤,就除了 ARMS 提供的默認大盤之外,你還可以基於 Grafana,把業務數據、應用數據,甚至容器數據放在一起,來去定製統一監控大盤。比如說雙 11 大促,或日常線上應急場景,都可以去快速地瀏覽整個業務線的表現,能夠快速地定位到問題的大致範圍。

第四步,當建立監控之外,還需要有一個比較有效的告警機制,因爲大家平時也不太會去一直盯着監控或者是 Trace 控制檯,肯定需要有應急入口,告警其實就是我們運維的第一入口。在這裏介紹三個比較典型的告警實踐。

比如說公司或者是團隊在剛起步或新產品剛上線的時候,很多東西都是比較缺失的。這個時候,我們可以通過 ARMS 的告警模板能力,把比較通用的應用、容器、中間件的告警能力能夠快速地構建出來,解決從 0 到 1 的問題。

當團隊或者是公司一步步成長起來,數據會越來越多,系統會越來越多。等到膨脹到一定程度時,告警可能分散在多個系統之中。這個時候又會帶來效率問題,就可以使用 ARMS 的告警能力,把多個告警源的數據放在一起去分析,甚至可以去做組合過濾規則。比如,當流量突然激增,性能後端的耗時變高,CPU 打滿的時候,發出建議擴容或是建議降級的告警通知。

當企業進一步地發展,發展得很好,團隊越來越多,人員越來越多。這個時候,可能一個系統會有很多個團隊來共同的去協作運維,我們不僅僅需要解決數據爆炸問題,還需要解決人員協同的問題。這個時候就可以基於 ARMS 的 ChatOps 能力來解決應急協同問題。

第五步,即使前面都做了之後,還有很多公司有建設自己專屬平臺的意願,因爲可能大家已經有了比較好的可觀測或監控報警方面的經驗以及場景沉澱,只需擴充部分這樣的能力,是完全可以基於 ARMS 這種開放數據的能力。無論是通過外部頁面的嵌入,還是 Open API 建設,或是直接把存儲開放出來,進行批量數據分析,都可以更好地完成二次開發。

四、最佳實踐

最後,我們來介紹常見實踐案例。比如,調用鏈通常聚合成一個應用維度的拓撲,或者是服務維度的拓撲,但這個時候往往還不夠,還可能會更關注某特定場景。

同樣是下單場景,有時候關注整體的下單還不夠,可能還需要關注某個新渠道或新上線品類。我們可能需要看某個線下零售的渠道,它的下單鏈路情況是怎麼樣的。或者是某個新品類,需要把這一部分業務場景單獨剝離出來,去做鏈路染色,從而能夠實現這一部分特定業務場景的應用和依賴的梳理。這個就是通過無侵入的業務染色實現的。

第二部分,ARMS Agent 除了做可觀測數據之外,同時也具備安全數據、安全行爲檢測與保護的能力,面對最近比較火的 Log4j2 高危核彈級漏洞,基於 RASP 技術就可以有很好的自我防護能力。即使不改代碼,也可以通過動態配置的方式,完成安全防護。除了安全防護之外,RASP 也可以提供攻擊溯源或者漏洞定位分析等等能力,相比於傳統的防火牆式保護會更有效一些。因爲它跟 IDC 防火牆的區別,有點像我們戴口罩和打疫苗這樣的一個區別。

第三個場景,在容器場景下實現全景監控,可以把來自於 Prometheus 或者 Loki 或者 eBPF、APM 等端到端數據放在一起,通過 2D、3D 拓撲,進行全程展示和端到端鏈路的下端分析。同時,我們還提供定期巡檢,或是基於專家經驗和算法的問題自動診斷和上報,這個就是我們在容器場景下的一個全景監控的最佳實踐。

第四個場景,一些架構比較複雜的用戶,具備多雲以及跨雲部署;出於數據安全考慮,也可能會去自建機房進行混合雲部署。爲了解決前後端、多語言、跨雲部署的問題,ARMS 的全鏈路追蹤幫助用戶完成複雜場景的全鏈路追蹤挑戰,把各種場景的鏈路串聯在一起,最大化去釋放鏈路跟蹤價值。

第五部分,就是說 ARMS 最近新上線了 Trace Explore 功能,相對於傳統調用鏈查詢和應用服務統計、監控之外,還提供實時獲取和分析能力。舉個簡單例子,我們經常要看耗時大於三秒的請求分佈在哪些接口或者是哪些 IP 上面,從而進行慢接口的處理,或單機故障排查診斷。這個時候我們在預聚合的時候,肯定沒辦法把耗時大於三秒或者是某一個特定的過濾條件等於什麼的場景之下,去做一個預先統計。這個時候我們就需要一個靈活的後聚合分析的能力。這個就是 Trace Explorer 能夠提供這樣的一個價值。除了我們剛剛說的這種單機慢接口之外,如果我們再結合我們的業務指標,比如說我們把我們的一些用戶的等級也打到我們的 Attributes 裏面對吧?我們就可以去按不同的用戶等級來去分析它的一些流量的情況,它響應的一些時延,就能夠更方便的低代碼的去完成這樣的一個自定義的分析。當然,這裏還舉了一個灰度監控,如果我們在重啓之前,比方說我們在環境變量裏面注入我們當前的版本,我們就可以看到不同版本之間一個流量和性能的變化。

最後,給出了一些 ARMS 相對於開源做的更好的最佳實踐。比如說接口偶發性超時的時候,接口級的調用鏈,還不足以診斷更新,我們需要完整的方法棧,但是那個問題現場已經過去了,怎麼能夠自動幫你保存下來呢?那就是可以通過 ARMS 線程剖析自動診斷的這樣的一個能力。

當我們微服務或者是數據庫的性能值打滿時,這個時候可能所有的請求都會變慢,但是你在調用鏈上也很難直觀的去反映出來,因爲這種資源類的問題是很難通過鏈路去記錄下來的。這個時候 ARMS 提供的這種池化監控,能夠直接分析每一類線程當前情況,並配置告警。除此之外比如說你想分析一些內存泄漏的問題,或者是一些線上運行代碼和本地行爲不一致的問題,都可以通過白屏化的內存診斷,或者是 Arthas 這種在線調試的這樣的一個能力,幫你快速的去定位你的根因。以上就是今天我們對鏈路追蹤整體的介紹,也涉及到我們對整個全鏈路追蹤的一些最佳的實踐,感謝大家!

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/rHvHGjboUEXTB2p8ifC39Q