主流微服務全鏈路監控系統之戰

問題背景

隨着微服務架構的流行,服務按照不同的維度進行拆分,一次請求往往需要涉及到多個服務。

互聯網應用構建在不同的軟件模塊集上,這些軟件模塊,有可能是由不同的團隊開發、可能使用不同的編程語言來實現、有可能布在了幾千臺服務器,橫跨多個不同的數據中心。

因此,就需要一些可以幫助理解系統行爲、用於分析性能問題的工具,以便發生故障的時候,能夠快速定位和解決問題。

全鏈路監控組件就在這樣的問題背景下產生了。最出名的是谷歌公開的論文提到的 Google Dapper。

想要在這個上下文中理解分佈式系統的行爲,就需要監控那些橫跨了不同的應用、不同的服務器之間的關聯動作。

所以,在複雜的微服務架構系統中,幾乎每一個前端請求都會形成一個複雜的分佈式服務調用鏈路。一個請求完整調用鏈可能如下圖所示:

那麼在業務規模不斷增大、服務不斷增多以及頻繁變更的情況下,面對複雜的調用鏈路就帶來一系列問題:

  1. 如何快速發現問題?

  2. 如何判斷故障影響範圍?

  3. 如何梳理服務依賴以及依賴的合理性?

  4. 如何分析鏈路性能問題以及實時容量規劃?

同時我們會關注在請求處理期間各個調用的各項性能指標,比如:吞吐量(TPS)、響應時間及錯誤記錄等。

  1. 吞吐量,根據拓撲可計算相應組件、平臺、物理設備的實時吞吐量。

  2. 響應時間,包括整體調用的響應時間和各個服務的響應時間等。

  3. 錯誤記錄,根據服務返回統計單位時間異常次數。

全鏈路性能監控從整體維度到局部維度展示各項指標,將跨應用的所有調用鏈性能信息集中展現,可方便度量整體和局部性能,並且方便找到故障產生的源頭,生產上可極大縮短故障排除時間。

有了全鏈路監控工具,我們能夠達到:

  1. 請求鏈路追蹤,故障快速定位:可以通過調用鏈結合業務日誌快速定位錯誤信息。

  2. 可視化:各個階段耗時,進行性能分析。

  3. 依賴優化:各個調用環節的可用性、梳理服務依賴關係以及優化。

  4. 數據分析,優化鏈路:可以得到用戶的行爲路徑,彙總分析應用在很多業務場景。

1 目標要求

如上所述,那麼我們選擇全鏈路監控組件有哪些目標要求呢?Google Dapper 中也提到了,總結如下:

1、探針的性能消耗

APM 組件服務的影響應該做到足夠小。服務調用埋點本身會帶來性能損耗,這就需要調用跟蹤的低損耗,實際中還會通過配置採樣率的方式,選擇一部分請求去分析請求路徑。在一些高度優化過的服務,即使一點點損耗也會很容易察覺到,而且有可能迫使在線服務的部署團隊不得不將跟蹤系統關停。

2、代碼的侵入性

即也作爲業務組件,應當儘可能少入侵或者無入侵其他業務系統,對於使用方透明,減少開發人員的負擔。

對於應用的程序員來說,是不需要知道有跟蹤系統這回事的。如果一個跟蹤系統想生效,就必須需要依賴應用的開發者主動配合,那麼這個跟蹤系統也太脆弱了,往往由於跟蹤系統在應用中植入代碼的 bug 或疏忽導致應用出問題,這樣纔是無法滿足對跟蹤系統 “無所不在的部署” 這個需求。

3、可擴展性

一個優秀的調用跟蹤系統必須支持分佈式部署,具備良好的可擴展性。能夠支持的組件越多當然越好。或者提供便捷的插件開發 API,對於一些沒有監控到的組件,應用開發者也可以自行擴展。

4、數據的分析

數據的分析要快 ,分析的維度儘可能多。跟蹤系統能提供足夠快的信息反饋,就可以對生產環境下的異常狀況做出快速反應。分析的全面,能夠避免二次開發。

2 功能模塊

一般的全鏈路監控系統,大致可分爲四大功能模塊:

1. 埋點與生成日誌

埋點即系統在當前節點的上下文信息,可以分爲 客戶端埋點、服務端埋點,以及客戶端和服務端雙向型埋點。埋點日誌通常要包含以下內容 traceId、spanId、調用的開始時間,協議類型、調用方 ip 和端口,請求的服務名、調用耗時,調用結果,異常信息等,同時預留可擴展字段,爲下一步擴展做準備;

不能造成性能負擔:一個價值未被驗證,卻會影響性能的東西,是很難在公司推廣的!

因爲要寫 log,業務 QPS 越高,性能影響越重。通過採樣和異步 log 解決。

2. 收集和存儲日誌

主要支持分佈式日誌採集的方案,同時增加 MQ 作爲緩衝;

  1. 每個機器上有一個 deamon 做日誌收集,業務進程把自己的 Trace 發到 daemon,daemon 把收集 Trace 往上一級發送;

  2. 多級的 collector,類似 pub/sub 架構,可以負載均衡;

  3. 對聚合的數據進行 實時分析和離線存儲;

  4. 離線分析 需要將同一條調用鏈的日誌彙總在一起;

3. 分析和統計調用鏈路數據,以及時效性

調用鏈跟蹤分析:把同一 TraceID 的 Span 收集起來,按時間排序就是 timeline。把 ParentID 串起來就是調用棧。

拋異常或者超時,在日誌裏打印 TraceID。利用 TraceID 查詢調用鏈情況,定位問題。

依賴度量:

  1. 強依賴:調用失敗會直接中斷主流程

  2. 高度依賴:一次鏈路中調用某個依賴的幾率高

  3. 頻繁依賴:一次鏈路調用同一個依賴的次數多

離線分析: 按 TraceID 彙總,通過 Span 的 ID 和 ParentID 還原調用關係,分析鏈路形態。

實時分析: 對單條日誌直接分析,不做彙總,重組。得到當前 QPS,延遲。

4. 展現以及決策支持

3 Google Dapper

3.1 Span

基本工作單元,一次鏈路調用(可以是 RPC,DB 等沒有特定的限制)創建一個 span,通過一個 64 位 ID 標識它,uuid 較爲方便,span 中還有其他的數據,例如描述信息,時間戳,key-value 對的(Annotation)tag 信息,parent_id 等,其中 parent-id 可以表示 span 調用鏈路來源。

上圖說明了 span 在一次大的跟蹤過程中是什麼樣的。Dapper 記錄了 span 名稱,以及每個 span 的 ID 和父 ID,以重建在一次追蹤過程中不同 span 之間的關係。如果一個 span 沒有父 ID 被稱爲 root span。所有 span 都掛在一個特定的跟蹤上,也共用一個跟蹤 id。

Span 數據結構:

3.2 Trace

類似於 樹結構的 Span 集合,表示一次完整的跟蹤,從請求到服務器開始,服務器返回 response 結束,跟蹤每次 rpc 調用的耗時,存在唯一標識 trace_id。比如:你運行的分佈式大數據存儲一次 Trace 就由你的一次請求組成。

每種顏色的 note 標註了一個 span,一條鏈路通過 TraceId 唯一標識,Span 標識發起的請求信息。樹節點是整個架構的基本單元,而每一個節點又是對 span 的引用。節點之間的連線表示的 span 和它的父 span 直接的關係。雖然 span 在日誌文件中只是簡單的代表 span 的開始和結束時間,他們在整個樹形結構中卻是相對獨立的。

3.3 Annotation

註解,用來記錄請求特定事件相關信息(例如時間),一個 span 中會有多個 annotation 註解描述。通常包含四個註解信息:

(1) cs:Client Start,表示客戶端發起請求
(2) sr:Server Receive,表示服務端收到請求
(3) ss:Server Send,表示服務端完成處理,並將結果發送給客戶端
(4) cr:Client Received,表示客戶端獲取到服務端返回信息

Annotation 數據結構:

type Annotation struct {
    Timestamp int64
    Value     string
    Host      Endpoint
    Duration  int32
}

3.4 調用示例

1. 請求調用示例

  1. 當用戶發起一個請求時,首先到達前端 A 服務,然後分別對 B 服務和 C 服務進行 RPC 調用;

  2. B 服務處理完給 A 做出響應,但是 C 服務還需要和後端的 D 服務和 E 服務交互之後再返還給 A 服務,最後由 A 服務來響應用戶的請求;

2. 調用過程追蹤

  1. 請求到來生成一個全局 TraceID,通過 TraceID 可以串聯起整個調用鏈,一個 TraceID 代表一次請求。

  2. 除了 TraceID 外,還需要 SpanID 用於記錄調用父子關係。每個服務會記錄下 parent id 和 span id,通過他們可以組織一次完整調用鏈的父子關係。

  3. 一個沒有 parent id 的 span 成爲 root span,可以看成調用鏈入口。

  4. 所有這些 ID 可用全局唯一的 64 位整數表示;

  5. 整個調用過程中每個請求都要透傳 TraceID 和 SpanID。

  6. 每個服務將該次請求附帶的 TraceID 和附帶的 SpanID 作爲 parent id 記錄下,並且將自己生成的 SpanID 也記錄下。

  7. 要查看某次完整的調用則 只要根據 TraceID 查出所有調用記錄,然後通過 parent id 和 span id 組織起整個調用父子關係。

3. 調用鏈核心工作

  1. 調用鏈數據生成,對整個調用過程的所有應用進行埋點並輸出日誌。

  2. 調用鏈數據採集,對各個應用中的日誌數據進行採集。

  3. 調用鏈數據存儲及查詢,對採集到的數據進行存儲,由於日誌數據量一般都很大,不僅要能對其存儲,還需要能提供快速查詢。

  4. 指標運算、存儲及查詢,對採集到的日誌數據進行各種指標運算,將運算結果保存起來。

  5. 告警功能,提供各種閥值警告功能。

4. 整體部署架構

5. AGENT 無侵入部署

通過 AGENT 代理無侵入式部署,將性能測量與業務邏輯完全分離,可以測量任意類的任意方法的執行時間,這種方式大大提高了採集效率,並且減少運維成本。根據服務跨度主要分爲兩大類 AGENT:

  1. 服務內 AGENT,這種方式是通過 Java 的 agent 機制,對服務內部的方法調用層次信息進行數據收集,如方法調用耗時、入參、出參等信息。

  2. 跨服務 AGENT,這種情況需要對主流 RPC 框架以插件形式提供無縫支持。並通過提供標準數據規範以適應自定義 RPC 框架:

(1)Dubbo支持; (2)Rest支持; (3)自定義RPC支持;

6. 調用鏈監控好處

  1. 準確掌握生產一線應用部署情況;

  2. 從調用鏈全流程性能角度,識別對關鍵調用鏈,並進行優化;

  3. 提供可追溯的性能數據,量化 IT 運維部門業務價值;

  4. 快速定位代碼性能問題,協助開發人員持續性的優化代碼;

  5. 協助開發人員進行白盒測試,縮短系統上線穩定期;

4 方案比較

市面上的全鏈路監控理論模型大多都是借鑑 Google Dapper 論文,本文重點關注以下三種 APM 組件:

  1. Zipkin:由 Twitter 公司開源,開放源代碼分佈式的跟蹤系統,用於收集服務的定時數據,以解決微服務架構中的延遲問題,包括:數據的收集、存儲、查找和展現。

  2. Pinpoint:一款對 Java 編寫的大規模分佈式系統的 APM 工具,由韓國人開源的分佈式跟蹤組件。

  3. Skywalking:國產的優秀 APM 組件,是一個對 JAVA 分佈式應用程序集羣的業務運行情況進行追蹤、告警和分析的系統。

以上三種全鏈路監控方案需要對比的項提煉出來:

  1. 探針的性能
    主要是 agent 對服務的吞吐量、CPU 和內存的影響。微服務的規模和動態性使得數據收集的成本大幅度提高。

2.collector 的可擴展性
能夠水平擴展以便支持大規模服務器集羣。

  1. 全面的調用鏈路數據分析
    提供代碼級別的可見性以便輕鬆定位失敗點和瓶頸。

  2. 對於開發透明,容易開關
    添加新功能而無需修改代碼,容易啓用或者禁用。

  3. 完整的調用鏈應用拓撲
    自動檢測應用拓撲,幫助你搞清楚應用的架構

4.1 探針的性能

比較關注探針的性能,畢竟 APM 定位還是工具,如果啓用了鏈路監控組建後,直接導致吞吐量降低過半,那也是不能接受的。對 skywalking、zipkin、pinpoint 進行了壓測,並與基線(未使用探針)的情況進行了對比。

選用了一個常見的基於 Spring 的應用程序,包含 Spring Boot, Spring MVC,redis 客戶端,mysql。監控這個應用程序,每個 trace,探針會抓取 5 個 span(1 Tomcat, 1 SpringMVC, 2 Jedis, 1 Mysql)。這邊基本和 skywalkingtest 的測試應用差不多。

模擬了三種併發用戶:500,750,1000。使用 jmeter 測試,每個線程發送 30 個請求,設置思考時間爲 10ms。使用的採樣率爲 1,即 100%,這邊與生產可能有差別。pinpoint 默認的採樣率爲 20,即 50%,通過設置 agent 的配置文件改爲 100%。zipkin 默認也是 1。組合起來,一共有 12 種。下面看下彙總表:

從上表可以看出,在三種鏈路監控組件中,skywalking 的探針對吞吐量的影響最小,zipkin 的吞吐量居中。pinpoint 的探針對吞吐量的影響較爲明顯,在 500 併發用戶時,測試服務的吞吐量從 1385 降低到 774,影響很大。然後再看下 CPU 和 memory 的影響,在內部服務器進行的壓測,對 CPU 和 memory 的影響都差不多在 10% 之內。

4.2 collector 的可擴展性

collector 的可擴展性,使得能夠水平擴展以便支持大規模服務器集羣。

1. zipkin

開發 zipkin-Server(其實就是提供的開箱即用包),zipkin-agent 與 zipkin-Server 通過 http 或者 mq 進行通信,http 通信會對正常的訪問造成影響,所以還是推薦基於 mq 異步方式通信,zipkin-Server 通過訂閱具體的 topic 進行消費。這個當然是可以擴展的,多個 zipkin-Server 實例進行異步消費 mq 中的監控信息。

2. skywalking

skywalking 的 collector 支持兩種部署方式:單機和集羣模式。collector 與 agent 之間的通信使用了 gRPC。

3. pinpoint

同樣,pinpoint 也是支持集羣和單機部署的。pinpoint agent 通過 thrift 通信框架,發送鏈路信息到 collector。

4.3 全面的調用鏈路數據分析

全面的調用鏈路數據分析,提供代碼級別的可見性以便輕鬆定位失敗點和瓶頸。

zipkin

zipkin 的鏈路監控粒度相對沒有那麼細,從上圖可以看到調用鏈中具體到接口級別,再進一步的調用信息並未涉及。

skywalking

skywalking 還支持 20 + 的中間件、框架、類庫,比如:主流的 dubbo、Okhttp,還有 DB 和消息中間件。上圖 skywalking 鏈路調用分析截取的比較簡單,網關調用 user 服務,由於支持衆多的中間件,所以 skywalking 鏈路調用分析比 zipkin 完備些。

pinpoint

pinpoint 應該是這三種 APM 組件中,數據分析最爲完備的組件。提供代碼級別的可見性以便輕鬆定位失敗點和瓶頸,上圖可以看到對於執行的 sql 語句,都進行了記錄。還可以配置報警規則等,設置每個應用對應的負責人,根據配置的規則報警,支持的中間件和框架也比較完備。

4.4 對於開發透明,容易開關

對於開發透明,容易開關,添加新功能而無需修改代碼,容易啓用或者禁用。我們期望功能可以不修改代碼就工作並希望得到代碼級別的可見性。

對於這一點,Zipkin 使用修改過的類庫和它自己的容器 (Finagle) 來提供分佈式事務跟蹤的功能。但是,它要求在需要時修改代碼。skywalking 和 pinpoint 都是基於字節碼增強的方式,開發人員不需要修改代碼,並且可以收集到更多精確的數據因爲有字節碼中的更多信息。

4.5 完整的調用鏈應用拓撲

自動檢測應用拓撲,幫助你搞清楚應用的架構。

pinpoint 鏈路拓撲

skywalking 鏈路拓撲

zipkin 鏈路拓撲

上面三幅圖,分別展示了 APM 組件各自的調用拓撲,都能實現完整的調用鏈應用拓撲。相對來說,pinpoint 界面顯示的更加豐富,具體到調用的 DB 名,zipkin 的拓撲侷限於服務於服務之間。

4.6 Pinpoint 與 Zipkin 細化比較

4.6.1 Pinpoint 與 Zipkin 差異性

  1. Pinpoint 是一個完整的性能監控解決方案:有從探針、收集器、存儲到 Web 界面等全套體系;而 Zipkin 只側重收集器和存儲服務,雖然也有用戶界面,但其功能與 Pinpoint 不可同日而語。反而 Zipkin 提供有 Query 接口,更強大的用戶界面和系統集成能力,可以基於該接口二次開發實現。

  2. Zipkin 官方提供有基於 Finagle 框架(Scala 語言)的接口,而其他框架的接口由社區貢獻,目前可以支持 Java、Scala、Node、Go、Python、Ruby 和 C# 等主流開發語言和框架;但是 Pinpoint 目前只有官方提供的 Java Agent 探針,其他的都在請求社區支援中(請參見 #1759 和 #1760)。

  3. Pinpoint 提供有 Java Agent 探針,通過字節碼注入的方式實現調用攔截和數據收集,可以做到真正的代碼無侵入,只需要在啓動服務器的時候添加一些參數,就可以完成探針的部署;而 Zipkin 的 Java 接口實現 Brave,只提供了基本的操作 API,如果需要與框架或者項目集成的話,就需要手動添加配置文件或增加代碼。

  4. Pinpoint 的後端存儲基於 HBase,而 Zipkin 基於 Cassandra。

4.6.2 Pinpoint 與 Zipkin 相似性

Pinpoint 與 Zipkin 都是基於 Google Dapper 的那篇論文,因此理論基礎大致相同。兩者都是將服務調用拆分成若干有級聯關係的 Span,通過 SpanId 和 ParentSpanId 來進行調用關係的級聯;最後再將整個調用鏈流經的所有的 Span 匯聚成一個 Trace,報告給服務端的 collector 進行收集和存儲。

即便在這一點上,Pinpoint 所採用的概念也不完全與那篇論文一致。比如他採用 TransactionId 來取代 TraceId,而真正的 TraceId 是一個結構,裏面包含了 TransactionId, SpanId 和 ParentSpanId。而且 Pinpoint 在 Span 下面又增加了一個 SpanEvent 結構,用來記錄一個 Span 內部的調用細節(比如具體的方法調用等等),因此 Pinpoint 默認會比 Zipkin 記錄更多的跟蹤數據。

但是理論上並沒有限定 Span 的粒度大小,所以一個服務調用可以是一個 Span,那麼每個服務中的方法調用也可以是個 Span,這樣的話,其實 Brave 也可以跟蹤到方法調用級別,只是具體實現並沒有這樣做而已。

4.6.3 字節碼注入 vs API 調用

Pinpoint 實現了基於字節碼注入的 Java Agent 探針,而 Zipkin 的 Brave 框架僅僅提供了應用層面的 API,但是細想問題遠不那麼簡單。字節碼注入是一種簡單粗暴的解決方案,理論上來說無論任何方法調用,都可以通過注入代碼的方式實現攔截,也就是說沒有實現不了的,只有不會實現的。但 Brave 則不同,其提供的應用層面的 API 還需要框架底層驅動的支持,才能實現攔截。

比如,MySQL 的 JDBC 驅動,就提供有注入 interceptor 的方法,因此只需要實現 StatementInterceptor 接口,並在 Connection String 中進行配置,就可以很簡單的實現相關攔截;而與此相對的,低版本的 MongoDB 的驅動或者是 Spring Data MongoDB 的實現就沒有如此接口,想要實現攔截查詢語句的功能,就比較困難。

因此在這一點上,Brave 是硬傷,無論使用字節碼注入多麼困難,但至少也是可以實現的,但是 Brave 卻有無從下手的可能,而且是否可以注入,能夠多大程度上注入,更多的取決於框架的 API 而不是自身的能力。

4.6.4 難度及成本

經過簡單閱讀 Pinpoint 和 Brave 插件的代碼,可以發現兩者的實現難度有天壤之別。在都沒有任何開發文檔支撐的前提下,Brave 比 Pinpoint 更容易上手。Brave 的代碼量很少,核心功能都集中在 brave-core 這個模塊下,一箇中等水平的開發人員,可以在一天之內讀懂其內容,並且能對 API 的結構有非常清晰的認識。

Pinpoint 的代碼封裝也是非常好的,尤其是針對字節碼注入的上層 API 的封裝非常出色,但是這依然要求閱讀人員對字節碼注入多少有一些瞭解,雖然其用於注入代碼的核心 API 並不多,但要想了解透徹,恐怕還得深入 Agent 的相關代碼,比如很難一目瞭然的理解 addInterceptor 和 addScopedInterceptor 的區別,而這兩個方法就是位於 Agent 的有關類型中。

因爲 Brave 的注入需要依賴底層框架提供相關接口,因此並不需要對框架有一個全面的瞭解,只需要知道能在什麼地方注入,能夠在注入的時候取得什麼數據就可以了。就像上面的例子,我們根本不需要知道 MySQL 的 JDBC Driver 是如何實現的也可以做到攔截 SQL 的能力。但是 Pinpoint 就不然,因爲 Pinpoint 幾乎可以在任何地方注入任何代碼,這需要開發人員對所需注入的庫的代碼實現有非常深入的瞭解,通過查看其 MySQL 和 Http Client 插件的實現就可以洞察這一點,當然這也從另外一個層面說明 Pinpoint 的能力確實可以非常強大,而且其默認實現的很多插件已經做到了非常細粒度的攔截。

針對底層框架沒有公開 API 的時候,其實 Brave 也並不完全無計可施,我們可以採取 AOP 的方式,一樣能夠將相關攔截注入到指定的代碼中,而且顯然 AOP 的應用要比字節碼注入簡單很多。

以上這些直接關係到實現一個監控的成本,在 Pinpoint 的官方技術文檔中,給出了一個參考數據。如果對一個系統集成的話,那麼用於開發 Pinpoint 插件的成本是 100,將此插件集成入系統的成本是 0;但對於 Brave,插件開發的成本只有 20,而集成成本是 10。從這一點上可以看出官方給出的成本參考數據是 5:1。但是官方又強調了,如果有 10 個系統需要集成的話,那麼總成本就是 10 * 10 + 20 = 120,就超出了 Pinpoint 的開發成本 100,而且需要集成的服務越多,這個差距就越大。

4.6.5 通用性和擴展性

很顯然,這一點上 Pinpoint 完全處於劣勢,從社區所開發出來的集成接口就可見一斑。

Pinpoint 的數據接口缺乏文檔,而且也不太標準(參考論壇討論帖),需要閱讀很多代碼纔可能實現一個自己的探針(比如 Node 的或者 PHP 的)。而且團隊爲了性能考慮使用了 Thrift 作爲數據傳輸協議標準,比起 HTTP 和 JSON 而言難度增加了不少。

4.6.6 社區支持

這一點也不必多說,Zipkin 由 Twitter 開發,可以算得上是明星團隊,而 Naver 的團隊只是一個默默無聞的小團隊(從 #1759 的討論中可以看出)。雖然說這個項目在短期內不太可能消失或停止更新,但畢竟不如前者用起來更加放心。而且沒有更多社區開發出來的插件,讓 Pinpoint 只依靠團隊自身的力量完成諸多框架的集成實屬困難,而且他們目前的工作重點依然是在提升性能和穩定性上。

4.6.7 其他

Pinpoint 在實現之初就考慮到了性能問題,www.naver.com 網站的後端某些服務每天要處理超過 200 億次的請求,因此他們會選擇 Thrift 的二進制變長編碼格式、而且使用 UDP 作爲傳輸鏈路,同時在傳遞常量的時候也儘量使用數據參考字典,傳遞一個數字而不是直接傳遞字符串等等。這些優化也增加了系統的複雜度:包括使用 Thrift 接口的難度、UDP 數據傳輸的問題、以及數據常量字典的註冊問題等等。

相比之下,Zipkin 使用熟悉的 Restful 接口加 JSON,幾乎沒有任何學習成本和集成難度,只要知道數據傳輸結構,就可以輕易的爲一個新的框架開發出相應的接口。

另外 Pinpoint 缺乏針對請求的採樣能力,顯然在大流量的生產環境下,不太可能將所有的請求全部記錄,這就要求對請求進行採樣,以決定什麼樣的請求是我需要記錄的。Pinpoint 和 Brave 都支持採樣百分比,也就是百分之多少的請求會被記錄下來。但是,除此之外 Brave 還提供了 Sampler 接口,可以自定義採樣策略,尤其是當進行 A/B 測試的時候,這樣的功能就非常有意義了。

4.6.8 總結

從短期目標來看,Pinpoint 確實具有壓倒性的優勢:無需對項目代碼進行任何改動就可以部署探針、追蹤數據細粒化到方法調用級別、功能強大的用戶界面以及幾乎比較全面的 Java 框架支持。但是長遠來看,學習 Pinpoint 的開發接口,以及未來爲不同的框架實現接口的成本都還是個未知數。

相反,掌握 Brave 就相對容易,而且 Zipkin 的社區更加強大,更有可能在未來開發出更多的接口。在最壞的情況下,我們也可以自己通過 AOP 的方式添加適合於我們自己的監控代碼,而並不需要引入太多的新技術和新概念。而且在未來業務發生變化的時候,Pinpoint 官方提供的報表是否能滿足要求也不好說,增加新的報表也會帶來不可以預測的工作難度和工作量。

5 Tracing 和 Monitor 區別

Monitor 可分爲系統監控和應用監控。系統監控比如 CPU,內存,網絡,磁盤等等整體的系統負載的數據,細化可具體到各進程的相關數據。這一類信息是直接可以從系統中得到的。應用監控需要應用提供支持,暴露了相應的數據。比如應用內部請求的 QPS,請求處理的延時,請求處理的 error 數,消息隊列的隊列長度,崩潰情況,進程垃圾回收信息等等。Monitor 主要目標是發現異常,及時報警。

Tracing 的基礎和核心都是調用鏈。相關的 metric 大多都是圍繞調用鏈分析得到的。Tracing 主要目標是系統分析。提前找到問題比出現問題後再去解決更好。

Tracing 和應用級的 Monitor 技術棧上有很多共同點。都有數據的採集,分析,存儲和展式。只是具體收集的數據維度不同,分析過程不一樣。

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