我們最近升級改造我們鏈路跟蹤系統Log2,然後我們花了將近一週時間調研不少開源的鏈路跟蹤系統,在此調研過程中,做了一些筆記和總結,若有誤請指教。

一、背景:分佈式系統的問題

在分佈式系統架構裏面,往往包含衆多應用服務,這些服務之間通過RPC調用來完成業務請求,如果其中某個RPC請求異常、超時和錯誤,很難去定位。這時我們需要分佈式鏈路跟蹤,去跟進請求鏈路到底有哪些服務,請求參數、請求結果、超時異常等情況,就可以清晰可見,然後監控服務運行狀況和快速定位問題。

例如:在分佈式微服務系統中,一個來自用戶的請求,請求先達到網關接口A,然後網關接口通過遠程調用A,B服務獲取結果最終,A服務調用後端算法服務C、D,算法服務D需要需要訪問ES, 這樣經過一系列服務調用後最後將數據返回。經歷了這麼多個服務,怎麼樣將它的請求過程的數據記錄下來呢?在各種服務之間調用我們面臨主要問題:

1、監控問題:如何快速發現和定位問題?即如何做好鏈路監控,及時掌握系統健康狀況和實時瞭解自身的業務運行情況。

2、故障問題:如何判斷故障影響範圍?  某個服務出現問題後,可以判斷對系統哪些服務有影響。

3、依賴問題:如何梳理服務依賴以及依賴的合理性? 服務依賴是否存在逆向或者循環調用。

4、性能分析:如何分析鏈路性能問題和容量規劃?對於激增的流量可以有應急方案和準備。

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

  1. 吞吐量 ,根據拓撲可計算相應組件、平臺、物理設備的實時吞吐量。
  2. 響應時間 ,包括整體調用的響應時間和各個服務的響應時間等。
  3. 錯誤記錄 ,根據服務返回統計單位時間異常次數。

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

在這種情況下,一般都會引入APM(Application Performance Management & Monitoring應用性能監控管理)系統,通過各種探針採集數據,收集關鍵指標,同時搭配數據呈現和監控告警,能夠解決上述的大部分問題。

二、APM需求

Google開源的 Dapper鏈路追蹤組件,並在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》(即《 Dapper,大規模分佈式系統的跟蹤系統》),這篇文章是業內實現鏈路追蹤的標杆和理論基礎,具有非常大的參考價值。

Dapper 的基本思路 :是在服務調用的請求和響應中加入SpanID,標明上下游請求的關係。利用這些跟蹤信息,可以可視化地分析服務調用鏈路和服務間的依賴關係。

《 Dapper,大規模分佈式系統的跟蹤系統》,總結如下:

1、APM功能模塊

1)、埋點與生成日誌

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

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

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

2)、收集和存儲日誌

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

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

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

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

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

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

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

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

依賴度量:

  1. 強依賴 :調用失敗會直接中斷主流程
  2. 高度依賴 :一次鏈路中調用某個依賴的幾率高
  3. 頻繁依賴 :一次鏈路調用同一個依賴的次數多

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

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

4)、展現以及決策支持

2、APM技術目標

1)、探針的性能消耗

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

2)、代碼的侵入性

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

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

3)、可擴展性

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

4)、數據的分析

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

三、開源APM系統

在谷歌論文《 Dapper,大規模分佈式系統的跟蹤系統》的指導下,許多優秀開源的APM系統應運而生。

目前市面上開源的APM系統主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是參考Google的 Dapper 實現。

1、各個開源APM簡介

CAT:是由國內美團點評開源的,基於Java語言開發,目前提供Java、C/C++、Node.js、Python、Go等語言的客戶端,監控數據會全量統計,國內很多公司在用,例如美團點評、攜程、拼多多等。從網上相關資源查閱:集成方案是通過代碼埋點的方式來實現監控,比如: 攔截器,註解,過濾器等。 對代碼的侵入性很大,集成成本較高。風險較大。

Zipkin:由Twitter公司開發並開源,Java語言實現。如果是基於spring cloud 微服務系統,結合spring-cloud-sleuth使用較爲簡單, 集成很方便。

Pinpoint:一個韓國團隊開源的產品,運用了字節碼增強技術,只需要在啓動時添加啓動參數即可,對代碼 無侵入 ,目前支持Java和PHP語言,底層採用HBase來存儲數據,探針收集的數據粒度非常細,但性能損耗大,因其出現的時間較長,完成度也很高,應用的公司較多

SkyWalking: 國人開源的產品,主要開發人員來自於華爲 ,2019年4月17日Apache董事會批准SkyWalking成爲頂級項目,支持Java、.Net、NodeJs等探針,數據存儲支持Mysql、Elasticsearch等,跟Pinpoint一樣採用字節碼注入的方式實現代碼的 無侵入 ,探針採集數據粒度粗,但性能表現優秀,且對雲原生支持,目前增長勢頭強勁,社區活躍,中文文檔沒有語言障礙

2、功能技術比較

面對各種鏈式追蹤系統開源,我們如何選擇:

1、結合公司自身情況:包括系統複雜度、使用技術棧。

2、根據上面提到APM的技術需求:探針的性能消耗、代碼的侵入性、可擴展性、數據分析的指標來選擇。

cat zipkin pinpoint skywalking
依賴

Java 6,7,8

Maven 3.2.3+

mysql5.6

Linux 2.6以及之上(2.6內核纔可以支持epoll)

Java 6,7,8

Maven3.2+

rabbitMQ

Java 6,7,8

maven3+

Hbase0.94+

Java 6,7,8

maven3.0+

nodejs

zookeeper

elasticsearch

實現方式 代碼埋點(攔截器,註解,過濾器等) 攔截請求,發送(HTTP,mq)數據至zipkin服務 java探針,字節碼增強 java探針,字節碼增強
存儲選擇 mysql , hdfs in-memory , mysql , Cassandra , Elasticsearch HBase elasticsearch , mysql、H2
通信方式 http , MQ thrift GRPC
MQ監控 不支持 不支持 不支持 支持(RocketMQ,kafka)
全局調用統計 支持 不支持 支持 支持
trace查詢 不支持 支持 不支持 支持
報警 支持 不支持 支持 支持
JVM監控 不支持 不支持 支持 支持
star數 4.5K 7.9K 5.6K 2.8K
優點 功能完善。

spring-cloud-sleuth可以很好的集成zipkin , 代碼無侵入,集成非常簡單 , 社區更加活躍。

對外提供有query接口,更加容易二次開發

完全無侵入, 僅需修改啓動方式,界面完善,功能細緻。

完全無侵入,界面完善,支持應用拓撲圖及單個調用鏈查詢。

功能比較完善(zipkin + pinpoint)

缺點

1、代碼侵入性較強,需要埋點

2、文檔比較混亂,文檔與發佈版本的符合性較低,需要依賴點評私服 (或者需要把他私服上的jar手動下載下來,然後上傳到我們的私服上去)。

1、默認使用的是http請求向zipkin上報信息,耗性能。

2、跟sleuth結合可以使用rabbitMQ的方式異步來做,增加了複雜度,需要引入rabbitMQ 。

3、數據分析比較簡單。

1、不支持查詢單個調用鏈, 對外表現的是整個應用的調用生態。

2、二次開發難度較高

1、3.2版本之前BUG較多 ,網上反映兼容性較差 . 3.2新版本的反映情況較少

2、依賴較多。

文檔 網上資料較少,僅官網提供的文檔,比較亂 文檔完善 文檔完善 文檔完善
開發者 大衆點評 twitter naver 吳晟(華爲開發者) ,目前已經加入Apache孵化器
支持技術棧 dubbo
spring mvc ,spring aop ,springmvc-url
spring boot
mybatis
log4j , logback
playframework
http請求
dubbo
spring mvc
spring boot
Tomcat 6+, Jetty 8/9, JBoss 6, Resin 4, Websphere 6+, Vertx 3.3+
Spring, Spring Boot (Embedded Tomcat, Jetty)
HTTP Client 3.x/4.x, HttpConnector, GoogleHttpClient, OkHttpClient, NingAsyncHttpClient
Thrift, Dubbo
mysql, oracle, mssql, cubrid,PostgreSQL, maria
arcus, memcached, redis, cassandra
MyBatis
DBCP, DBCP2, HIKARICP
gson, Jackson, Json Lib
log4j, Logback
Tomcat7+ , resin3+, jetty
spring boot ,spring mvc
strtuts2
spring RestTemplete ,spring-cloud-feign
okhttp , httpClient
msyql ,oracle , H2 , sharding-jdbc,PostgreSQL
dubbo,dubbox ,motan, gRpc ,
rocketMq , kafla
redis, mongoDB,memcached ,
elastic-job , Netflix Eureka , Hystric
使用公司 大衆點評, 攜程, 陸金所,同程旅遊,獵聘網 twitter naver 華爲軟件開發雲、天源迪科、噹噹網、京東金融
客戶端支持語言 JavaScript,Python,Java, Scala, Ruby, C#, Go Java,.NETCore ,PHP, Python和 NodeJS

3、性能比較

我們沒有實際測試這些組件的性能:摘自 https://juejin.im/post/5a7a9e0af265da4e914b46f1

比較關注探針的性能,畢竟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、collector的可擴展性

zipkin

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

skywalking

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

pinpoint

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

===================================================================

參考: https://juejin.im/post/5a7a9e0af265da4e914b46f1

相關文章