APM 原理與框架選型


發些存稿:)

0. APM簡介

隨着微服務架構的流行,一次請求往往需要涉及到多個服務,因此服務性能監控和排查就變得更復雜:

  • 不同的服務可能由不同的團隊開發、甚至可能使用不同的編程語言來實現
  • 服務有可能布在了幾千台服務器,橫跨多個不同的數據中心

因此,就需要一些可以幫助理解系統行為、用於分析性能問題的工具,以便發生故障的時候,能夠快速定位和解決問題,這就是APM系統,全稱是(Application Performance Monitor,當然也有叫 Application Performance Management tools)

AMP最早是谷歌公開的論文提到的 Google Dapper。Dapper是Google生產環境下的分布式跟蹤系統,自從Dapper發展成為一流的監控系統之后,給google的開發者和運維團隊幫了大忙,所以谷歌公開論文分享了Dapper。

1. 谷歌Dapper介紹

1.1 Dapper的挑戰

在google的首頁頁面,提交一個查詢請求后,會經歷什么:

  • 可能對上百台查詢服務器發起了一個Web查詢,每一個查詢都有自己的Index
  • 這個查詢可能會被發送到多個的子系統,這些子系統分別用來處理廣告、進行拼寫檢查或是查找一些像圖片、視頻或新聞這樣的特殊結果
  • 根據每個子系統的查詢結果進行篩選,得到最終結果,最后匯總到頁面上

總結一下:

  • 一次全局搜索有可能調用上千台服務器,涉及各種服務。
  • 用戶對搜索的耗時是很敏感的,而任何一個子系統的低效都導致導致最終的搜索耗時

如果一次查詢耗時不正常,工程師怎么來排查到底是由哪個服務調用造成的?

  • 首先,這個工程師可能無法准確的定位到這次全局搜索是調用了哪些服務,因為新的服務、乃至服務上的某個片段,都有可能在任何時間上過線或修改過,有可能是面向用戶功能,也有可能是一些例如針對性能或安全認證方面的功能改進
  • 其次,你不能苛求這個工程師對所有參與這次全局搜索的服務都了如指掌,每一個服務都有可能是由不同的團隊開發或維護的
  • 再次,這些暴露出來的服務或服務器有可能同時還被其他客戶端使用着,所以這次全局搜索的性能問題甚至有可能是由其他應用造成的

從上面可以看出Dapper需要:

  • 無所不在的部署,無所不在的重要性不言而喻,因為在使用跟蹤系統的進行監控時,即便只有一小部分沒被監控到,那么人們對這個系統是不是值得信任都會產生巨大的質疑
  • 持續的監控

1.2 Dapper的三個具體設計目標

  1. 性能消耗低

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

  2. 應用透明,也就是代碼的侵入性小

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

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

  3. 可擴展性

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

  4. 數據的分析

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

1.3 Dapper的分布式跟蹤原理

先來看一次請求調用示例:

  1. 包括:前端(A),兩個中間層(B和C),以及兩個后端(D和E)
  2. 當用戶發起一個請求時,首先到達前端A服務,然后分別對B服務和C服務進行RPC調用;
  3. B服務處理完給A做出響應,但是C服務還需要和后端的D服務和E服務交互之后再返還給A服務,最后由A服務來響應用戶的請求;

Dapper的分布式跟蹤

Dapper是如何來跟蹤記錄這次請求呢?

1.3.1 跟蹤樹和span

Span是dapper的基本工作單元,一次鏈路調用(可以是RPC,DB等沒有特定的限制)創建一個span,通過一個64位ID標識它;同時附加(Annotation)作為payload負載信息,用於記錄性能等數據。

5個span在Dapper跟蹤樹種短暫的關聯關系

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

再來看下Span的細節

一個單獨的span的細節圖

Span數據結構

type Span struct {
    TraceID    int64 // 用於標示一次完整的請求id
    Name       string
    ID         int64 // 當前這次調用span_id
    ParentID   int64 // 上層服務的調用span_id  最上層服務parent_id為null
    Annotation []Annotation // 用於標記的時間戳
    Debug      bool
}

1.3.2 TraceID

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

Trace

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

1.3.3 Annotation

Dapper允許應用程序開發人員在Dapper跟蹤的過程中添加額外的信息,以監控更高級別的系統行為,或幫助調試問題。這就是Annotation:

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
}

1.3.4 采樣率

低損耗的是Dapper的一個關鍵的設計目標,因為如果這個工具價值未被證實但又對性能有影響的話,你可以理解服務運營人員為什么不願意部署它。

另外,某些類型的Web服務對植入帶來的性能損耗確實非常敏感。

因此,除了把Dapper的收集工作對基本組件的性能損耗限制的盡可能小之外,Dapper支持設置采樣率來減少性能損耗,同時支持可變采樣

2. APM組件選型

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

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

2.1 對比項

主要對比項:

  1. 探針的性能

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

  2. collector的可擴展性

    能夠水平擴展以便支持大規模服務器集群。

  3. 全面的調用鏈路數據分析

    提供代碼級別的可見性以便輕松定位失敗點和瓶頸。

  4. 對於開發透明,容易開關

    添加新功能而無需修改代碼,容易啟用或者禁用。

  5. 完整的調用鏈應用拓撲

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

2.2 探針的性能

比較關注探針的性能,畢竟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%之內。

2.3 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

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

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

zipkin

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

skywalking

skywalking

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

pinpoint

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

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

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

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

2.6 完整的調用鏈應用拓撲

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

zipkin鏈路拓撲:
zipkin鏈路拓撲

skywalking鏈路拓撲:

skywalking鏈路拓撲

pinpoint

三個組件都能實現完整的調用鏈應用拓撲。相對來說:

  • pinpoint界面顯示的更加豐富,具體到調用的DB名
  • zipkin的拓撲局限於服務於服務之間

2.7 社區支持

Zipkin 由 Twitter 開發,可以算得上是明星團隊,而 pinpoint的Naver 的團隊只是一個默默無聞的小團隊,skywalking是國內的明星項目,目前屬於apache孵化項目,社區活躍。

2.8 總結

zipkin pinpoint skywalking
探針性能
collector擴展性
調用鏈路數據分析
對開發透明性
調用鏈應用拓撲
社區支持

相對來說,skywalking更占優,因此團隊采用skywalking作為APM工具。

3. 參考內容

本文主要內容參考下文:
https://juejin.im/post/5a7a9e0af265da4e914b46f1
http://bigbully.github.io/Dapper-translation/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM