国产在线观看精品免费,亚洲日本VA久久一区二区,香蕉久久99综合一区二区三区,久久精品99国产精品蜜桃小说

主流微服務(wù)全鏈路監控系統之戰

2021-11-04 09:24:24 shuai.chang

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

問(wèn)題背景

隨著(zhù)微服務(wù)架構的流行,服務(wù)按照不同的維度進(jìn)行拆分,一次請求往往需要涉及到多個(gè)服務(wù)。

互聯(lián)網(wǎng)應用構建在不同的軟件模塊集上,這些軟件模塊,有可能是由不同的團隊開(kāi)發(fā)、可能使用不同的編程語(yǔ)言來(lái)實(shí)現、有可能布在了幾千臺服務(wù)器,橫跨多個(gè)不同的數據中心。

因此,就需要一些可以幫助理解系統行為、用于分析性能問(wèn)題的工具,以便發(fā)生故障的時(shí)候,能夠快速定位和解決問(wèn)題。

全鏈路監控組件就在這樣的問(wèn)題背景下產(chǎn)生了。最出名的是谷歌公開(kāi)的論文提到的 Google Dapper。

想要在這個(gè)上下文中理解分布式系統的行為,就需要監控那些橫跨了不同的應用、不同的服務(wù)器之間的關(guān)聯(lián)動(dòng)作。

所以,在復雜的微服務(wù)架構系統中,幾乎每一個(gè)前端請求都會(huì )形成一個(gè)復雜的分布式服務(wù)調用鏈路。一個(gè)請求完整調用鏈可能如下圖所示:

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
那么在業(yè)務(wù)規模不斷增大、服務(wù)不斷增多以及頻繁變更的情況下,面對復雜的調用鏈路就帶來(lái)一系列問(wèn)題:

  1. 如何快速發(fā)現問(wèn)題?
  2. 如何判斷故障影響范圍?
  3. 如何梳理服務(wù)依賴(lài)以及依賴(lài)的合理性?
  4. 如何分析鏈路性能問(wèn)題以及實(shí)時(shí)容量規劃?

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

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

  2. 響應時(shí)間,包括整體調用的響應時(shí)間和各個(gè)服務(wù)的響應時(shí)間等。

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

全鏈路性能監控從整體維度到局部維度展示各項指標,將跨應用的所有調用鏈性能信息集中展現,可方便度量整體和局部性能,并且方便找到故障產(chǎn)生的源頭,生產(chǎn)上可極大縮短故障排除時(shí)間。
有了全鏈路監控工具,我們能夠達到:

  1. 請求鏈路追蹤,故障快速定位:可以通過(guò)調用鏈結合業(yè)務(wù)日志快速定位錯誤信息。
  2. 可視化:各個(gè)階段耗時(shí),進(jìn)行性能分析。
  3. 依賴(lài)優(yōu)化:各個(gè)調用環(huán)節的可用性、梳理服務(wù)依賴(lài)關(guān)系以及優(yōu)化。
  4. 數據分析,優(yōu)化鏈路:可以得到用戶(hù)的行為路徑,匯總分析應用在很多業(yè)務(wù)場(chǎng)景。

1 目標要求

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

1、探針的性能消耗

APM 組件服務(wù)的影響應該做到足夠小。服務(wù)調用埋點(diǎn)本身會(huì )帶來(lái)性能損耗,這就需要調用跟蹤的低損耗,實(shí)際中還會(huì )通過(guò)配置采樣率的方式,選擇一部分請求去分析請求路徑。在一些高度優(yōu)化過(guò)的服務(wù),即使一點(diǎn)點(diǎn)損耗也會(huì )很容易察覺(jué)到,而且有可能迫使在線(xiàn)服務(wù)的部署團隊不得不將跟蹤系統關(guān)停。

2、代碼的侵入性

即也作為業(yè)務(wù)組件,應當盡可能少入侵或者無(wú)入侵其他業(yè)務(wù)系統,對于使用方透明,減少開(kāi)發(fā)人員的負擔。

對于應用的程序員來(lái)說(shuō),是不需要知道有跟蹤系統這回事的。如果一個(gè)跟蹤系統想生效,就必須需要依賴(lài)應用的開(kāi)發(fā)者主動(dòng)配合,那么這個(gè)跟蹤系統也太脆弱了,往往由于跟蹤系統在應用中植入代碼的 bug 或疏忽導致應用出問(wèn)題,這樣才是無(wú)法滿(mǎn)足對跟蹤系統“無(wú)所不在的部署”這個(gè)需求。

3、可擴展性

一個(gè)優(yōu)秀的調用跟蹤系統必須支持分布式部署,具備良好的可擴展性。能夠支持的組件越多當然越好?;蛘咛峁┍憬莸牟寮_(kāi)發(fā)API,對于一些沒(méi)有監控到的組件,應用開(kāi)發(fā)者也可以自行擴展。

4、數據的分析

數據的分析要快 ,分析的維度盡可能多。跟蹤系統能提供足夠快的信息反饋,就可以對生產(chǎn)環(huán)境下的異常狀況做出快速反應。分析的全面,能夠避免二次開(kāi)發(fā)。

2 功能模塊

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

1.埋點(diǎn)與生成日志

埋點(diǎn)即系統在當前節點(diǎn)的上下文信息,可以分為 客戶(hù)端埋點(diǎn)、服務(wù)端埋點(diǎn),以及客戶(hù)端和服務(wù)端雙向型埋點(diǎn)。埋點(diǎn)日志通常要包含以下內容traceId、spanId、調用的開(kāi)始時(shí)間,協(xié)議類(lèi)型、調用方ip和端口,請求的服務(wù)名、調用耗時(shí),調用結果,異常信息等,同時(shí)預留可擴展字段,為下一步擴展做準備;

不能造成性能負擔:一個(gè)價(jià)值未被驗證,卻會(huì )影響性能的東西,是很難在公司推廣的!
因為要寫(xiě) log,業(yè)務(wù) QPS 越高,性能影響越重。通過(guò)采樣和異步log解決。

2.收集和存儲日志

主要支持分布式日志采集的方案,同時(shí)增加 MQ 作為緩沖;

  1. 每個(gè)機器上有一個(gè) deamon 做日志收集,業(yè)務(wù)進(jìn)程把自己的 Trace 發(fā)到 daemon,daemon 把收集 Trace 往上一級發(fā)送;

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

  3. 對聚合的數據進(jìn)行 實(shí)時(shí)分析和離線(xiàn)存儲;

  4. 離線(xiàn)分析 需要將同一條調用鏈的日志匯總在一起;

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

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

拋異?;蛘叱瑫r(shí),在日志里打印 TraceID。利用 TraceID 查詢(xún)調用鏈情況,定位問(wèn)題。

依賴(lài)度量:

  1. 強依賴(lài):調用失敗會(huì )直接中斷主流程

  2. 高度依賴(lài):一次鏈路中調用某個(gè)依賴(lài)的幾率高

  3. 頻繁依賴(lài):一次鏈路調用同一個(gè)依賴(lài)的次數多


離線(xiàn)分析:按TraceID匯總,通過(guò)Span的ID和ParentID還原調用關(guān)系,分析鏈路形態(tài)。

實(shí)時(shí)分析:對單條日志直接分析,不做匯總,重組。得到當前QPS,延遲。

4.展現以及決策支持

3 Google Dapper

3.1 Span

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

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

上圖說(shuō)明了 span 在一次大的跟蹤過(guò)程中是什么樣的。Dapper 記錄了 span 名稱(chēng),以及每個(gè) span 的 ID 和父 ID,以重建在一次追蹤過(guò)程中不同 span 之間的關(guān)系。如果一個(gè) span沒(méi)有父 ID 被稱(chēng)為 root span。所有 span 都掛在一個(gè)特定的跟蹤上,也共用一個(gè)跟蹤 id。

Span 數據結構:

type Span struct {TraceIDint64 // 用于標示一次完整的請求idName stringID int64 // 當前這次調用span_idParentID int64 // 上層服務(wù)的調用span_id最上層服務(wù)parent_id為nullAnnotation []Annotation // 用于標記的時(shí)間戳Debugbool}

3.2 Trace

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

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
Trace

每種顏色的note標注了一個(gè)span,一條鏈路通過(guò)TraceId唯一標識,Span標識發(fā)起的請求信息。樹(shù)節點(diǎn)是整個(gè)架構的基本單元,而每一個(gè)節點(diǎn)又是對span的引用。節點(diǎn)之間的連線(xiàn)表示的span和它的父span直接的關(guān)系。雖然span在日志文件中只是簡(jiǎn)單的代表span的開(kāi)始和結束時(shí)間,他們在整個(gè)樹(shù)形結構中卻是相對獨立的。

3.3 Annotation

注解,用來(lái)記錄請求特定事件相關(guān)信息(例如時(shí)間),一個(gè)span中會(huì )有多個(gè)annotation注解描述。通常包含四個(gè)注解信息:

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

Annotation數據結構:

type Annotation struct {Timestamp int64Value stringHostEndpointDurationint32}

3.4 調用示例

1. 請求調用示例

  1. 當用戶(hù)發(fā)起一個(gè)請求時(shí),首先到達前端A服務(wù),然后分別對B服務(wù)和C服務(wù)進(jìn)行RPC調用;

  2. B服務(wù)處理完給A做出響應,但是C服務(wù)還需要和后端的D服務(wù)和E服務(wù)交互之后再返還給A服務(wù),最后由A服務(wù)來(lái)響應用戶(hù)的請求;


睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
請求調用示例

2. 調用過(guò)程追蹤

  1. 請求到來(lái)生成一個(gè)全局 TraceID,通過(guò) TraceID 可以串聯(lián)起整個(gè)調用鏈,一個(gè)TraceID 代表一次請求。
  2. 除了TraceID外,還需要SpanID用于記錄調用父子關(guān)系。每個(gè)服務(wù)會(huì )記錄下parent id和span id,通過(guò)他們可以組織一次完整調用鏈的父子關(guān)系。
  3. 一個(gè)沒(méi)有parent id的span成為root span,可以看成調用鏈入口。
  4. 所有這些ID可用全局唯一的64位整數表示;
  5. 整個(gè)調用過(guò)程中每個(gè)請求都要透傳TraceID和SpanID。
  6. 每個(gè)服務(wù)將該次請求附帶的TraceID和附帶的SpanID作為parent id記錄下,并且將自己生成的SpanID也記錄下。
  7. 要查看某次完整的調用則 只要根據TraceID查出所有調用記錄,然后通過(guò)parent id和span id組織起整個(gè)調用父子關(guān)系。

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
整個(gè)調用過(guò)程追蹤

3. 調用鏈核心工作

  1. 調用鏈數據生成,對整個(gè)調用過(guò)程的所有應用進(jìn)行埋點(diǎn)并輸出日志。

  2. 調用鏈數據采集,對各個(gè)應用中的日志數據進(jìn)行采集。

  3. 調用鏈數據存儲及查詢(xún),對采集到的數據進(jìn)行存儲,由于日志數據量一般都很大,不僅要能對其存儲,還需要能提供快速查詢(xún)。

  4. 指標運算、存儲及查詢(xún),對采集到的日志數據進(jìn)行各種指標運算,將運算結果保存起來(lái)。

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

4. 整體部署架構

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

5. AGENT無(wú)侵入部署

通過(guò)AGENT代理無(wú)侵入式部署,將性能測量與業(yè)務(wù)邏輯完全分離,可以測量任意類(lèi)的任意方法的執行時(shí)間,這種方式大大提高了采集效率,并且減少運維成本。根據服務(wù)跨度主要分為兩大類(lèi)AGENT:

  1. 服務(wù)內AGENT,這種方式是通過(guò) Java 的agent機制,對服務(wù)內部的方法調用層次信息進(jìn)行數據收集,如方法調用耗時(shí)、入參、出參等信息。

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

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

6. 調用鏈監控好處

  1. 準確掌握生產(chǎn)一線(xiàn)應用部署情況;

  2. 從調用鏈全流程性能角度,識別對關(guān)鍵調用鏈,并進(jìn)行優(yōu)化;

  3. 提供可追溯的性能數據,量化 IT 運維部門(mén)業(yè)務(wù)價(jià)值;

  4. 快速定位代碼性能問(wèn)題,協(xié)助開(kāi)發(fā)人員持續性的優(yōu)化代碼;

  5. 協(xié)助開(kāi)發(fā)人員進(jìn)行白盒測試,縮短系統上線(xiàn)穩定期;

4 方案比較

市面上的全鏈路監控理論模型大多都是借鑒 Google Dapper 論文,本文重點(diǎn)關(guān)注以下三種 APM 組件:

  1. Zipkin:由Twitter公司開(kāi)源,開(kāi)放源代碼分布式的跟蹤系統,用于收集服務(wù)的定時(shí)數據,以解決微服務(wù)架構中的延遲問(wèn)題,包括:數據的收集、存儲、查找和展現。
  2. Pinpoint:一款對Java編寫(xiě)的大規模分布式系統的APM工具,由韓國人開(kāi)源的分布式跟蹤組件。
  3. Skywalking:國產(chǎn)的優(yōu)秀APM組件,是一個(gè)對JAVA分布式應用程序集群的業(yè)務(wù)運行情況進(jìn)行追蹤、告警和分析的系統。

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

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

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

3.全面的調用鏈路數據分析
提供代碼級別的可見(jiàn)性以便輕松定位失敗點(diǎn)和瓶頸。

4.對于開(kāi)發(fā)透明,容易開(kāi)關(guān)
添加新功能而無(wú)需修改代碼,容易啟用或者禁用。

5.完整的調用鏈應用拓撲
自動(dòng)檢測應用拓撲,幫助你搞清楚應用的架構

4.1 探針的性能

比較關(guān)注探針的性能,畢竟 APM 定位還是工具,如果啟用了鏈路監控組建后,直接導致吞吐量降低過(guò)半,那也是不能接受的。對 skywalking、zipkin、pinpoint 進(jìn)行了壓測,并與基線(xiàn)(未使用探針)的情況進(jìn)行了對比。
選用了一個(gè)常見(jiàn)的基于 Spring 的應用程序,包含 Spring Boot, Spring MVC,redis客戶(hù)端,mysql。監控這個(gè)應用程序,每個(gè)trace,探針會(huì )抓取5個(gè)span(1 Tomcat, 1 SpringMVC, 2 Jedis, 1 Mysql)。這邊基本和 skywalkingtest 的測試應用差不多。
模擬了三種并發(fā)用戶(hù):500,750,1000。使用jmeter測試,每個(gè)線(xiàn)程發(fā)送30個(gè)請求,設置思考時(shí)間為10ms。使用的采樣率為1,即100%,這邊與生產(chǎn)可能有差別。pinpoint默認的采樣率為20,即50%,通過(guò)設置agent的配置文件改為100%。zipkin默認也是1。組合起來(lái),一共有12種。下面看下匯總表:
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

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

4.2 collector的可擴展性

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

1. zipkin

開(kāi)發(fā) zipkin-Server(其實(shí)就是提供的開(kāi)箱即用包),zipkin-agent 與 zipkin-Server 通過(guò) http 或者 mq 進(jìn)行通信,http 通信會(huì )對正常的訪(fǎng)問(wèn)造成影響,所以還是推薦基于mq異步方式通信,zipkin-Server 通過(guò)訂閱具體的 topic 進(jìn)行消費。這個(gè)當然是可以擴展的,多個(gè) zipkin-Server 實(shí)例進(jìn)行異步消費 mq 中的監控信息。

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
zipkin
2. skywalking
skywalking的collector支持兩種部署方式:?jiǎn)螜C和集群模式。collector與agent之間的通信使用了gRPC。
3. pinpoint
同樣,pinpoint也是支持集群和單機部署的。pinpoint agent通過(guò)thrift通信框架,發(fā)送鏈路信息到collector。

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

全面的調用鏈路數據分析,提供代碼級別的可見(jiàn)性以便輕松定位失敗點(diǎn)和瓶頸。

zipkin
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

zipkin鏈路調用分析

zipkin 的鏈路監控粒度相對沒(méi)有那么細,從上圖可以看到調用鏈中具體到接口級別,再進(jìn)一步的調用信息并未涉及。
skywalking
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

skywalking鏈路調用分析

skywalking 還支持20+的中間件、框架、類(lèi)庫,比如:主流的dubbo、Okhttp,還有DB和消息中間件。上圖skywalking鏈路調用分析截取的比較簡(jiǎn)單,網(wǎng)關(guān)調用user服務(wù),由于支持眾多的中間件,所以skywalking鏈路調用分析比zipkin完備些。
pinpoint
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商

pinpoint鏈路調用分析

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

4.4 對于開(kāi)發(fā)透明,容易開(kāi)關(guān)

對于開(kāi)發(fā)透明,容易開(kāi)關(guān),添加新功能而無(wú)需修改代碼,容易啟用或者禁用。我們期望功能可以不修改代碼就工作并希望得到代碼級別的可見(jiàn)性。

對于這一點(diǎn),Zipkin 使用修改過(guò)的類(lèi)庫和它自己的容器(Finagle)來(lái)提供分布式事務(wù)跟蹤的功能。但是,它要求在需要時(shí)修改代碼。skywalking和pinpoint都是基于字節碼增強的方式,開(kāi)發(fā)人員不需要修改代碼,并且可以收集到更多精確的數據因為有字節碼中的更多信息。

4.5 完整的調用鏈應用拓撲

自動(dòng)檢測應用拓撲,幫助你搞清楚應用的架構。

睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
pinpoint鏈路拓撲
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
skywalking鏈路拓撲
睿智創(chuàng  )新RAIZ,一體化IT服務(wù)提供商
zipkin鏈路拓撲

上面三幅圖,分別展示了APM 組件各自的調用拓撲,都能實(shí)現完整的調用鏈應用拓撲。相對來(lái)說(shuō),pinpoint 界面顯示的更加豐富,具體到調用的DB名,zipkin的拓撲局限于服務(wù)于服務(wù)之間。

4.6 Pinpoint與Zipkin細化比較

4.6.1 Pinpoint與Zipkin差異性

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

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

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

  4. Pinpoint 的后端存儲基于 HBase,而 Zipkin 基于 Cassandra。

4.6.2 Pinpoint 與 Zipkin 相似性

Pinpoint 與 Zipkin 都是基于 Google Dapper 的那篇論文,因此理論基礎大致相同。兩者都是將服務(wù)調用拆分成若干有級聯(lián)關(guān)系的 Span,通過(guò) SpanId 和 ParentSpanId 來(lái)進(jìn)行調用關(guān)系的級聯(lián);最后再將整個(gè)調用鏈流經(jīng)的所有的 Span 匯聚成一個(gè) Trace,報告給服務(wù)端的 collector 進(jìn)行收集和存儲。

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

但是理論上并沒(méi)有限定 Span 的粒度大小,所以一個(gè)服務(wù)調用可以是一個(gè) Span,那么每個(gè)服務(wù)中的方法調用也可以是個(gè) Span,這樣的話(huà),其實(shí) Brave 也可以跟蹤到方法調用級別,只是具體實(shí)現并沒(méi)有這樣做而已。

4.6.3 字節碼注入 vs API 調用

Pinpoint 實(shí)現了基于字節碼注入的 Java Agent 探針,而 Zipkin 的 Brave 框架僅僅提供了應用層面的 API,但是細想問(wèn)題遠不那么簡(jiǎn)單。字節碼注入是一種簡(jiǎn)單粗暴的解決方案,理論上來(lái)說(shuō)無(wú)論任何方法調用,都可以通過(guò)注入代碼的方式實(shí)現攔截,也就是說(shuō)沒(méi)有實(shí)現不了的,只有不會(huì )實(shí)現的。但 Brave 則不同,其提供的應用層面的 API 還需要框架底層驅動(dòng)的支持,才能實(shí)現攔截。

比如,MySQL 的 JDBC 驅動(dòng),就提供有注入 interceptor 的方法,因此只需要實(shí)現 StatementInterceptor 接口,并在 Connection String 中進(jìn)行配置,就可以很簡(jiǎn)單的實(shí)現相關(guān)攔截;而與此相對的,低版本的 MongoDB 的驅動(dòng)或者是 Spring Data MongoDB 的實(shí)現就沒(méi)有如此接口,想要實(shí)現攔截查詢(xún)語(yǔ)句的功能,就比較困難。

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

4.6.4 難度及成本

經(jīng)過(guò)簡(jiǎn)單閱讀 Pinpoint 和 Brave 插件的代碼,可以發(fā)現兩者的實(shí)現難度有天壤之別。在都沒(méi)有任何開(kāi)發(fā)文檔支撐的前提下,Brave 比 Pinpoint 更容易上手。Brave 的代碼量很少,核心功能都集中在 brave-core 這個(gè)模塊下,一個(gè)中等水平的開(kāi)發(fā)人員,可以在一天之內讀懂其內容,并且能對 API 的結構有非常清晰的認識。

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

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

針對底層框架沒(méi)有公開(kāi) API 的時(shí)候,其實(shí) Brave 也并不完全無(wú)計可施,我們可以采取 AOP 的方式,一樣能夠將相關(guān)攔截注入到指定的代碼中,而且顯然 AOP 的應用要比字節碼注入簡(jiǎn)單很多。

以上這些直接關(guān)系到實(shí)現一個(gè)監控的成本,在 Pinpoint 的官方技術(shù)文檔中,給出了一個(gè)參考數據。如果對一個(gè)系統集成的話(huà),那么用于開(kāi)發(fā) Pinpoint 插件的成本是 100,將此插件集成入系統的成本是 0;但對于 Brave,插件開(kāi)發(fā)的成本只有 20,而集成成本是 10。從這一點(diǎn)上可以看出官方給出的成本參考數據是 5:1。但是官方又強調了,如果有 10 個(gè)系統需要集成的話(huà),那么總成本就是 10 * 10 + 20 = 120,就超出了 Pinpoint 的開(kāi)發(fā)成本 100,而且需要集成的服務(wù)越多,這個(gè)差距就越大。

4.6.5 通用性和擴展性

很顯然,這一點(diǎn)上 Pinpoint 完全處于劣勢,從社區所開(kāi)發(fā)出來(lái)的集成接口就可見(jiàn)一斑。

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

4.6.6 社區支持

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

4.6.7 其他

Pinpoint 在實(shí)現之初就考慮到了性能問(wèn)題,www.naver.com 網(wǎng)站的后端某些服務(wù)每天要處理超過(guò) 200 億次的請求,因此他們會(huì )選擇 Thrift 的二進(jìn)制變長(cháng)編碼格式、而且使用 UDP 作為傳輸鏈路,同時(shí)在傳遞常量的時(shí)候也盡量使用數據參考字典,傳遞一個(gè)數字而不是直接傳遞字符串等等。這些優(yōu)化也增加了系統的復雜度:包括使用 Thrift 接口的難度、UDP 數據傳輸的問(wèn)題、以及數據常量字典的注冊問(wèn)題等等。
相比之下,Zipkin 使用熟悉的 Restful 接口加 JSON,幾乎沒(méi)有任何學(xué)習成本和集成難度,只要知道數據傳輸結構,就可以輕易的為一個(gè)新的框架開(kāi)發(fā)出相應的接口。
另外 Pinpoint 缺乏針對請求的采樣能力,顯然在大流量的生產(chǎn)環(huán)境下,不太可能將所有的請求全部記錄,這就要求對請求進(jìn)行采樣,以決定什么樣的請求是我需要記錄的。Pinpoint 和 Brave 都支持采樣百分比,也就是百分之多少的請求會(huì )被記錄下來(lái)。但是,除此之外 Brave 還提供了 Sampler 接口,可以自定義采樣策略,尤其是當進(jìn)行 A/B 測試的時(shí)候,這樣的功能就非常有意義了。

4.6.8 總結

從短期目標來(lái)看,Pinpoint 確實(shí)具有壓倒性的優(yōu)勢:無(wú)需對項目代碼進(jìn)行任何改動(dòng)就可以部署探針、追蹤數據細?;椒椒ㄕ{用級別、功能強大的用戶(hù)界面以及幾乎比較全面的 Java 框架支持。但是長(cháng)遠來(lái)看,學(xué)習 Pinpoint 的開(kāi)發(fā)接口,以及未來(lái)為不同的框架實(shí)現接口的成本都還是個(gè)未知數。
相反,掌握 Brave 就相對容易,而且 Zipkin 的社區更加強大,更有可能在未來(lái)開(kāi)發(fā)出更多的接口。在最壞的情況下,我們也可以自己通過(guò) AOP 的方式添加適合于我們自己的監控代碼,而并不需要引入太多的新技術(shù)和新概念。而且在未來(lái)業(yè)務(wù)發(fā)生變化的時(shí)候,Pinpoint 官方提供的報表是否能滿(mǎn)足要求也不好說(shuō),增加新的報表也會(huì )帶來(lái)不可以預測的工作難度和工作量。

5 Tracing 和 Monitor 區別

Monitor 可分為系統監控和應用監控。系統監控比如CPU,內存,網(wǎng)絡(luò ),磁盤(pán)等等整體的系統負載的數據,細化可具體到各進(jìn)程的相關(guān)數據。這一類(lèi)信息是直接可以從系統中得到的。應用監控需要應用提供支持,暴露了相應的數據。比如應用內部請求的QPS,請求處理的延時(shí),請求處理的error數,消息隊列的隊列長(cháng)度,崩潰情況,進(jìn)程垃圾回收信息等等。Monitor主要目標是發(fā)現異常,及時(shí)報警。
Tracing 的基礎和核心都是調用鏈。相關(guān)的 metric 大多都是圍繞調用鏈分析得到的。Tracing 主要目標是系統分析。提前找到問(wèn)題比出現問(wèn)題后再去解決更好。
Tracing 和應用級的 Monitor 技術(shù)棧上有很多共同點(diǎn)。都有數據的采集,分析,存儲和展式。只是具體收集的數據維度不同,分析過(guò)程不一樣。


我要咨詢(xún)