架構設計(11)-- 分佈式鏈路跟蹤: 理論知識
我們最近升級改造我們鏈路跟蹤系統Log2,然後我們花了將近一週時間調研不少開源的鏈路跟蹤系統,在此調研過程中,做了一些筆記和總結,若有誤請指教。
一、背景:分佈式系統的問題
在分佈式系統架構裏面,往往包含衆多應用服務,這些服務之間通過RPC調用來完成業務請求,如果其中某個RPC請求異常、超時和錯誤,很難去定位。這時我們需要分佈式鏈路跟蹤,去跟進請求鏈路到底有哪些服務,請求參數、請求結果、超時異常等情況,就可以清晰可見,然後監控服務運行狀況和快速定位問題。
例如:在分佈式微服務系統中,一個來自用戶的請求,請求先達到網關接口A,然後網關接口通過遠程調用A,B服務獲取結果最終,A服務調用後端算法服務C、D,算法服務D需要需要訪問ES, 這樣經過一系列服務調用後最後將數據返回。經歷了這麼多個服務,怎麼樣將它的請求過程的數據記錄下來呢?在各種服務之間調用我們面臨主要問題:
1、監控問題:如何快速發現和定位問題?即如何做好鏈路監控,及時掌握系統健康狀況和實時瞭解自身的業務運行情況。
2、故障問題:如何判斷故障影響範圍? 某個服務出現問題後,可以判斷對系統哪些服務有影響。
3、依賴問題:如何梳理服務依賴以及依賴的合理性? 服務依賴是否存在逆向或者循環調用。
4、性能分析:如何分析鏈路性能問題和容量規劃?對於激增的流量可以有應急方案和準備。
同時我們會關注在請求處理期間各個調用的各項性能指標,比如:吞吐量(TPS)、響應時間及錯誤記錄等。
- 吞吐量 ,根據拓撲可計算相應組件、平臺、物理設備的實時吞吐量。
- 響應時間 ,包括整體調用的響應時間和各個服務的響應時間等。
- 錯誤記錄 ,根據服務返回統計單位時間異常次數。
全鏈路性能監控 從整體維度到局部維度展示各項指標 ,將跨應用的所有調用鏈性能信息集中展現,可方便度量整體和局部性能,並且方便找到故障產生的源頭,生產上可極大縮短故障排除時間。
在這種情況下,一般都會引入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查詢調用鏈情況,定位問題。
依賴度量:
- 強依賴 :調用失敗會直接中斷主流程
- 高度依賴 :一次鏈路中調用某個依賴的幾率高
- 頻繁依賴 :一次鏈路調用同一個依賴的次數多
離線分析:按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、依賴較多。 |
文檔 | 網上資料較少,僅官網提供的文檔,比較亂 | 文檔完善 | 文檔完善 | 文檔完善 |
開發者 | 大衆點評 | 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 |
使用公司 | 大衆點評, 攜程, 陸金所,同程旅遊,獵聘網 | 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 。
===================================================================