使用Skywalking实现全链路监控
https://opentalk.upyun.com/334.html
2017 年 10 月 29 日,又拍云 Open Talk 聯合 Spring Cloud 中國社區成功舉辦了“進擊的微服務實戰派北京站”。華為技術專家吳晟作了題為《使用 Skywalking 實現全鏈路監控》的分享,以下是分享實錄:
一、分布式追蹤
(一)三種場景
1、Metrics 指標性統計
比如說我們會去做一個服務的 TBS 的正確率、成功率、流量等,這是我們常見的針對單個指標或者某一個數據庫的,這就是 Metrics 單指標分析。
2、Tracing 分布式追蹤
這里提到的是一次請求的范圍,也就是我們從瀏覽器或者手機端發起任何的一次調用,甚至我們可以再推廣一點,是一次業務教育,比如說一次訂購的過程,從瀏覽商品到最后下定單、支付、物流、最后交到我們的手上。這是一個流程化的東西,我們需要軌跡,需要去追蹤。
3、?Logging 日志記錄
我們程序在執行的過程中間發生了一些日志,會一幀一幀地跳出來給大家去記錄這個東西,這是日志記錄。
如果你做一個監控的產品, 你需要明確自己的定位,每個領域實際上要關心的事情是不一樣的,而且這些領域之間會有交叉點。比如 Metrics 和 Logging 可能是之于某個指標的統計,但你通過日志的方式去做了一個搜集,最后統計了這些 Metrics 的信息,以及這些 Metrics 信息和對應的 Logging 的關系,那么你走的可能是 Metrics 和 Logging 之間的范圍。如果你要去做 Metrics 和 Logging 中間的這些點,你需要清楚你是不是要付出這么大的代價。因為你每去占到這個圓中的一個部分,你的系統復雜度、內存的開銷、后端的存儲都需要付出相應的代價。隨著指標數、內容的加入,你所要投入的研發技術難度也在逐步
上升。
所以大家在選擇使用某一個分布式監控系統的時候,一定要明確你使用它的目的是什么,精確地了解它們的定位!
(二)什么是分布式追蹤
?
上圖是常見的微服務的框架,4 個實例,2 個 MySQL、1 個 Redis。實際上它有兩次完全不同的請求進來:有一次的一個請求會訪問 Redis,再去訪問 MySQL;另外一個可能走到另外的服務上,然后直接去 MySQL。整個分布式追蹤的目的是什么?是為了讓我們最終在頁面上、UI上、和數據上能夠復現這個過程。我們要拿到整個完整的鏈路,包括精確的響應時間,訪問的方法、訪問的 circle,訪問的 Redis 的 key等,這些是我們在做分布式追蹤的時候需要展現的一個完整的信息。
(三)什么是 OpenTracing?
開發和工程團隊因為系統組件水平擴展、開發團隊小型化、敏捷開發、CD(持續集成)、解耦等各種需求,正在使用現代的微服務架構替換老舊的單片機系統。 也就是說,當一個生產系統面對真正的高并發,或者解耦成大量微服務時,以前很容易實現的重點任務變得困難了。過程中需要面臨一系列問題:用戶體驗優化、后臺真是錯誤原因分析,分布式系統內各組件的調用情況等。 當代分布式跟蹤系統(例如,Zipkin, Dapper, HTrace, X-Trace等)旨在解決這些問題,但是他們使用不兼容的API來實現各自的應用需求。盡管這些分布式追蹤系統有著相似的API語法,但各種語言的開發人員依然很難將他們各自的系統(使用不同的語言和技術)和特定的分布式追蹤系統進行整合,OpenTracing 通過提供平臺無關、廠商無關的 API,使得開發人員能夠方便的添加(或更換)追蹤系統的實現。 OpenTracing 提供了用于運營支撐系統的和針對特定平臺的輔助程序庫。
OpenTracing 是一個規范,它不是一個數據結構,能提供的是語音和概念。OpenTracing 要涵蓋的是中間的一層,它是要實現的是一套 API 的套件。你需要按照 OpenTracing 的規范向用戶提供 API,實現把數據下送到 API 的探針或者 Tracer 的探針。OpenTracing 的主旨是在做手動埋點,程序的開發者要主動調用 Tracing 的 API 。我們這里主要是在講 java ,而不是在講例如 go、c++、c 等不太好寫自動探針的語言。
二、Skywalking
SkyWalking 是針對分布式系統的 APM 系統,也被稱為分布式追蹤系統
- 全自動探針監控,不需要修改應用程序代碼。查看支持的中間件和組件庫列表:https://github.com/apache/incubator-skywalking
- 支持手動探針監控, 提供了支持 OpenTracing 標準的SDK。覆蓋范圍擴大到 OpenTracing-Java 支持的組件。查看OpenTracing組件支持列表:https://github.com/opentracing-contrib/meta
- 自動監控和手動監控可以同時使用,使用手動監控彌補自動監控不支持的組件,甚至私有化組件。
- 純 Java 后端分析程序,提供 RESTful 服務,可為其他語言探針提供分析能力。
- 高性能純流式分析。
Skywalking 是去搜集數據,給出分析的結果,然后你可以去做自動化運維或者 DveOps 。我們搜集的是 JVM 數據,然后去做自動的、應用的 Top 發現,以及服務的依賴。所以當你去做服務的時候,實際上服務會變成一顆服樹。而不是簡單的單個服務點,后面還會搜集服務訪問的指標以及成功率、服務的數量等,下一階段會提供 Alerting 報警。
Skywalking 的系統指標,做了一個壓測,在 5000 tps 的應用上,我們消耗 10% 左右的 CPU。內存沒有寫,因為內存取決于采集到的數據,比如 URL 的長短,circle 的長短等等。
我們會去做支持日志記錄集成,提供一個集成的方式,你可以把調用鏈的 ID 和日志做綁定,當你有 ELK 類型系統的時候,就可以讓它和 skywalking 一起工作。然后你的日志里會有 skywalking 調用鏈的 ID ,這個調用鏈的信息和這些日志是精確綁定的。如此,你可以更好的使用日志系統,而不用把日志系統做大規模的復雜的查詢,因為每一次的日志都是可以精確地匹配到一次精確地訪問上的。
Skywalking 支持多種實現,目前提供是 H2 和 Elastic Search ,Elastic Search 主要用于生產 H2 。目前已經支持了大概 30 個以上的 libraries 的庫,常見的基本都有。
(一)Skywalking 生態圈
目前有很多公司和個人在參加我們的項目,3 位 PMC 成員,2 位 Committer Team 成員,還有 15 個其他公司的貢獻者,包括華為、阿里、當當、云智慧、OneAPM 等。所以我們能夠提供很多大家看起來像是好像曾經你只能在商業產品或者國外看到的一些能力,因為我們很多人曾經或者現在都在專業的 APM 公司做過架構或者核心的研發工程師。
(二)Skywalking 3.2.3
sykwalking 3.2.3 架構圖
上圖是 skywalking 3.2.3 的整體架構圖。
首先針對 Adaptor layer ,我們會與大家合作去做更多的擴展,包括我們的探針,SW3 Cross Process Propagation Protocol ,這實際上是我們的規范, 這個規范也會和全球的其他 APM公司合作,去形成剛才談到的 TraceContext 的標準。我們會一起去努力把這個標準讓所有的Tracer 之間,能夠在一定程度上共享信息。也就是說當 A 應用調 B 應用的時候,即使 A、B 應用不屬于同一個系統的監控,但是它們都有分布式鏈路的追蹤能力,他們這個鏈路是有辦法讓大家串起來的。
我們之前和當當有做過一個嘗試,當當內部暫時沒有提供 php 和 golang 的探針,但他們可以在內部去通過簡單的日志系統或者手工埋探針的方式,來實現我們的規范,我們可以復用我們的 Collector 來實現跨語言的探針,這個是一個開放的力量,我們不需要去做所有的事情,你只需要補充一點周圍的事情,就可以滿足需求。
機械計算和告警會是下一個階段的重點,這塊我們會和京東金融的團隊有深度的合作,他們會和我們一起構建 base line 計算模塊,讓告警脫離手工設置,通過系統運行過程中做一個自動的計算,最后實際上不要超過平時太多,那么這個在線的系統就沒有問題。
(三)Skywalking 追蹤核心概念
這里反映了 skywalking 追蹤的核心概念以及我們做的事情,就是 skywalking 怎么采集調用鏈。實際上這個基本是 skywalking 內核的翻譯,里面可能會有一些可能在 OpenTracing 見到的概念,但也有一些我們自己的概念。
首先是第一級概念 TraceSegment ,一次訪問會跳過 3 個 JOM ,每個 JOM 里面會生成 4 個 Segment 。我們在一次調用里面,所經歷的一個線程,會生成一個 TraceSegment 。這里它經歷了 4 個線程,不管是否跨 JOM ,A 里面 1 個,B 里面 1 個,B 里面的 New Thread 1 個,C 里面 1 個,所以它經歷了四個線程后就會生成四 TraceSegment 對象。
對于入口,不管外圍調用是否前置,都會創建一個 entry span,然后走 Extract ,提取前置上下文,當然第一個點沒有前置,所以什么都沒拿到。然后會創建一個 exit span ,創建一個最出的埋點。之后會做一個 inject的操作,把當前的上下文放在 HTTP 的頭里面,順帶這個 HTTP的調用發到 Service B 上。
這個時候在運行的線程里面它一定會 hang 住,因為它需要等對方 HTTP 的返回,所以就會出現在 Service B 上,會同樣地創建 TraceSegment ,創建 entry ,然后 Extract 提取 ContextCarrier ,這時它與 1 肯定是不一樣的,因為前面做了 inject ,注入了上下文,因此這邊一定能夠拿到上下文,那么它就會做一個 Segment2 和 Segment1 的綁定關系。然后它又會它需要等對方 HTTP 的返回,所以就會出現在 Service B 上,會同樣地創建 TraceSegment ,創建 entry ,然后 Extract 提取 ContextCarrier ,這時它與 1 肯定是不一樣的,因為前面做了 inject ,注入了上下文,因此這邊一定能夠拿到上下文,那么它就會做一個 Segment2 和 Segment1 的綁定關系。然后它又會創建一個 exit ,跟前面一樣。
最后面 TraceSegment3 也是一樣的,Create 、Extract、exit、stop 退出來。
New Thread 這邊實際上起了一個新的線程,這里面的一些概念不是 OpenTracing 里面的。首先我們會做一個 Capture Snapshot 的操作,與 inject 的操作類似,但是里面的數據一個是跨線程,一個是跨進程,所以里面的數據實際上是不太一樣的,但是邏輯類似,把當前的上下文保存下來,然后把 Snapshot 傳遞到新線程里面,再做 Continued Snapshot ,把 sanpshot 繼續,這個繼續的操作會創建 TraceSegment4 ,因為你把以前的狀態做了狀態恢復。那么它創建了一個新的 TraceSegment ,同時有去做了一個綁定,這時候它在新線程里面跑的東西就似,把當前的上下文保存下來,然后把 Snapshot 傳遞到新線程里面,再做 Continued Snapshot ,把 sanpshot 繼續,這個繼續的操作會創建 TraceSegment4 ,因為你把以前的狀態做了狀態恢復。那么它創建了一個新的 TraceSegment ,同時有去做了一個綁定,這時候它在新線程里面跑的東西就會在新的 TraceSegment 去存儲它想要的信息。
這里描述的基本上是一個通行標準,你在所有的 APM 的產品里面都會見到類似的流程,大家可能做的事情不一樣,但是內容基本上都是一樣的。所以我這里拿到 skywalking 去做一個分析。
(四)演示實例
?
?演示環節用了一個非常簡單的 Spring Cloud 的例子,使用了 Spring Cloud 里面的 Netflix Eureka 等東西做了例子,以下是演示程序的源代碼:https://github.com/SkywalkingTest/spring-cloud-example?。
當網絡條件調用很好的時候,調用的情況如下圖:
調用情況
追蹤情況
JVM
服務依賴樹
演示實例詳情請觀看視頻資料。
轉載于:https://www.cnblogs.com/davidwang456/articles/9269826.html
總結
以上是生活随笔為你收集整理的使用Skywalking实现全链路监控的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微服务实践分享(5)缓存中心
- 下一篇: 微服务下的APM全链路监控