用SkyWalking做分布式追蹤和應用性能監控系統

【轉載請注明出處】:http://www.lxweimin.com/p/e1592d395891

SkyWalking 是觀察性分析平臺和應用性能管理系統。提供分布式追蹤、服務網格遙測分析、度量聚合和可視化一體化解決方案。

特性:

  • 多種監控手段,語言探針和service mesh
  • 多語言自動探針,Java,.NET Core和Node.JS
  • 輕量高效,不需要大數據
  • 模塊化,UI、存儲、集群管理多種機制可選
  • 支持告警
  • 優秀的可視化方案

Skywalking 技術架構

image.png

整個系統分為三部分:

  • agent:采集tracing(調用鏈數據)和metric(指標)信息并上報
  • OAP:收集tracing和metric信息通過analysis core模塊將數據放入持久化容器中(ES,H2(內存數據庫),mysql等等),并進行二次統計和監控告警
  • webapp:前后端分離,前端負責呈現,并將查詢請求封裝為graphQL提交給后端,后端通過ribbon做負載均衡轉發給OAP集群,再將查詢結果渲染展示

Skywalking也提供了其他的一些特性:

  • 配置重載:支持通過jvm參數覆寫默認配置,支持動態配置管理
  • 集群管理:這個主要體現在OAP,通過集群部署分擔數據上報的流量壓力和二次計算的計算壓力,同時集群也可以通過配置切換角色,分別面向數據采集(collector)和計算(aggregator,alarm),需要注意的是agent目前不支持多collector負載均衡,而是隨機從集群中選擇一個實例進行數據上報
  • 支持k8s和mesh
  • 支持數據容器的擴展,例如官方主推是ES,通過擴展接口,也可以實現插件去- - 支持其他的數據容器
  • 支持數據上報receiver的擴展,例如目前主要是支持gRPC接受agent的上報,但是也可以實現插件支持其他類型的數據上報(官方默認實現了對Zipkin,telemetry和envoy的支持)
  • 支持客戶端采樣和服務端采樣,不過服務端采樣最有意義
  • 官方制定了一個數據查詢腳本規范:OAL(Observability Analysis Language),語法類似Linq,以簡化數據查詢擴展的工作量
  • 支持監控預警,通過OAL獲取數據指標和閾值進行對比來觸發告警,支持webhook擴展告警方式,支持統計周期的自定義,以及告警靜默防止重復告警
數據容器

由于Skywalking并沒有自己定制的數據容器或者使用多種數據容器增加復雜度,而是主要使用ElasticSearch(當然開源的基本上都是這樣來保持簡潔,例如Pinpoint也只使用了HBase),所以數據容器的特性以及自己數據結構基本上就限制了業務的上限,以ES為例:

  • ES查詢功能異常強大,在數據篩選方面碾壓其他所有容器,在數據篩選潛力巨大(Skywalking默認的查詢維度就比使用HBase的Pinpoint強很多)
  • 支持sharding分片和replicas數據備份,在高可用/高性能/大數據支持都非常好
  • 支持批量插入,高并發下的插入性能大大增強
  • 數據密度低,源于ES會提前構建大量的索引來優化搜索查詢,這是查詢功能強大和性能好的代價,但是鏈路跟蹤往往有非常多的上下文需要記錄,所以Skywalking把這些上下文二進制化然后通過Base64編碼放入data_binary字段并且將字段標記為not_analyzed來避免進行預處理建立查詢索引

總體來說,Skywalking盡量使用ES在大數據和查詢方面的優勢,同時盡量減少ES數據密度低的劣勢帶來的影響,從目前來看,ES在調用鏈跟蹤方面是不二的數據容器,而在數據指標方面,ES也能中規中矩的完成業務,雖然和時序數據庫相比要弱一些,但在PB級以下的數據支持也不會有太大問題。

數據結構

如果說數據容器決定了上限,那么數據結構則決定了實際到達的高度。Skywalking的數據結構主要為:

  • 數據維度(ES索引為skywalking_*_inventory)
    1. service:服務
    2. instance:實例
    3. endpoint:接口
    4. network_adress:外部依賴
  • 數據內容
    1. 原始數據
    • 調用鏈跟蹤數據(調用鏈的trace信息,ES索引為skywalking_segment,Skywalking主要的數據消耗都在這里)
    • 指標(主要是jvm或者envoy的運行時指標,例如ES索引skywalking_instance_jvm_cpu)
    1. 二次統計指標
    • 指標(按維度/時間二次統計出來的例如pxx、sla等指標,例如ES索引skywalking_database_access_p75_month)
    • 數據庫慢查詢記錄(數據庫索引:skywalking_top_n_database_statement)
    1. 關聯關系(維度/指標之間的關聯關系,ES索引為skywalking_relation)
    2. 特別記錄
      • 告警信息(ES索引為skywalking_alarm_record)
      • 并發控制(ES索引為skywalking_register_lock)

其中數量占比最大的就是調用鏈跟蹤數據和各種指標,而這些數據均可以通過OAP設置過期時間,以降低歷史數據的對磁盤占用和查詢效率的影響。

調用鏈跟蹤數據

作為Skywalking的核心數據,調用鏈跟蹤數據(skywalking_segment)基本上奠定了整個系統的基礎,而如果要詳細的了解調用鏈跟蹤的話,就不得不提到openTracing

openTracing基本上是目前開源調用鏈跟蹤系統的一個事實標準,它制定了調用鏈跟蹤的基本流程和基本的數據結構,同時也提供了各個語言的實現。如果用一張圖來表現openTracing,則是如下:

openTracing基本結構

其中:

  • SpanContext:一個類似于MDC(Slfj)或者ThreadLocal的組件,負責整個調用鏈數據采集過程中的上下文保持和傳遞
  • Trace:一次調用的完整記錄
    • Span:一次調用中的某個節點/步驟,類似于一層堆棧信息,Trace是由多個Span組成,Span和Span之間也有父子或者并列的關系來標志這個節點/步驟在整個調用中的位置
      • Tag:節點/步驟中的關鍵信息
      • Log:節點/步驟中的詳細記錄,例如異常時的異常堆棧
    • Baggage:和SpanContext一樣并不屬于數據結構而是一種機制,主要用于跨Span或者跨實例的上下文傳遞,Baggage的數據更多是用于運行時,而不會進行持久化

以一個Trace為例:

span間的關系

首先是外部請求調用A,然后A依次同步調用了B和C,而B被調用時會去同步調用D,C被調用的時候會依次同步調用E和F,F被調用的時候會通過異步調用G,G則會異步調用H,最終完成一次調用。

上圖是通過Span之間的依賴關系來表現一個Trace,而在時間線上,則可以有如下的表達:

span的調用順序

當然,如果是同步調用的話,父Span的時間占用是包括子Span的時間消耗的。

而落地到Skywalking中,我們以一條skywalking_segment的記錄為例:

{
    "trace_id": "52.70.15530767312125341",
    "endpoint_name": "Mysql/JDBI/Connection/commit",
    "latency": 0,
    "end_time": 1553076731212,
    "endpoint_id": 96142,
    "service_instance_id": 52,
    "version": 2,
    "start_time": 1553076731212,
    "data_binary": "CgwKCjRGnPvp5eikyxsSXhD///////////8BGMz62NSZLSDM+tjUmS0wju8FQChQAVgBYCF6DgoHZGIudHlwZRIDc3FsehcKC2RiLmluc3RhbmNlEghyaXNrZGF0YXoOCgxkYi5zdGF0ZW1lbnQYAiA0",
    "service_id": 2,
    "time_bucket": 20190320181211,
    "is_error": 0,
    "segment_id": "52.70.15530767312125340"
}

其中:

  • trace_id:本次調用的唯一id,通過snowflake模式生成
  • endpoint_name:被調用的接口
  • latency:耗時
  • end_time:結束時間戳
  • endpoint_id:被調用的接口的唯一id
  • service_instance_id:被調用的實例的唯一id
  • version:本數據結構的版本號
  • start_time:開始時間戳
  • data_binary:里面保存了本次調用的所有Span的數據,序列化并用Base64編碼,不會進行分析和用于查詢
  • service_id:服務的唯一id
  • time_bucket:調用所處的時段
  • is_error:是否失敗
  • segment_id:數據本身的唯一id,類似于主鍵,通過snowflake模式生成

這里可以看到,目前Skywalking雖然相較于Pinpoint來說查詢的維度要多一些,但是也很有限,而且除了endPoint,并沒有和業務有關聯的字段,只能通過時間/服務/實例/接口/成功標志/耗時來進行非業務相關的查詢,如果后續要增強業務相關的搜索查詢的話,應該還需要增加一些用于保存動態內容(如messageId,orderId等業務關鍵字)的字段用于快速定位

指標

指標數據相對于Tracing則要簡單得多了,一般來說就是指標標志、時間戳、指標值,而Skywalking中的指標有兩種:一種是采集的原始指標值,例如jvm的各種運行時指標(例如cpu消耗、內存結構、GC信息等);一種是各種二次統計指標(例如tp性能指標、SLA等,當然也有為了便于查詢的更高時間維度的指標,例如基于分鐘、小時、天、周、月)

例如以下是索引skywalking_endpoint_cpm_hour中的一條記錄,用于標志一個小時內某個接口的cpm指標:

{
    "total": 8900,
    "service_id": 5,
    "time_bucket": 2019031816,
    "service_instance_id": 5,
    "entity_id": "7",
    "value": 148
}

各個字段的釋義如下:

  • total:一分鐘內的調用總量
  • service_id:所屬服務的唯一id
  • time_bucket:統計的時段
  • service_instance_id:所屬實例的唯一id
  • entity_id:接口(endpoint)的唯一id
  • value:cpm的指標值(cpm=call per minute,即total/60)
agent

agent(apm-sniffer)是Skywalking的Java探針實現,主要負責:

  • 采集應用實例的jvm指標
  • 通過切向編程進行數據埋點,采集調用鏈數據
  • 通過RPC將采集的數據上報

當然,agent還實現了客戶端采樣,不過在APM監控系統里進行客戶端數據采樣都是沒有靈魂的,所以這里就不再贅述了。

首先,agent通過 org.apache.skywalking.apm.agent.core.boot.BootService 實現了整體的插件化,agent啟動會加載所有的BootService實現,并通過 ServiceManager 來管理這些插件的生命周期,采集jvm指標、gRPC連接管理、調用鏈數據維護、數據上報OAP這些服務均是通過這種方式擴展。

然后,agent還通過bytebuddy以javaagent的模式,通過字節碼增強的機制來構造AOP環境,再提供PluginDefine的規范方便探針的開發,最終實現非侵入性的數據埋點,采集調用鏈數據。

OAP

同agent類似,OAP作為Skywalking最核心的模塊,也實現了自己的擴展機制,不過在這里叫做Module,具體可以參考library-module,在module的機制下,Skywalking實現了自己必須核心組件:

  • core:整個OAP核心業務(remoting、cluster、storage、analysis、query、alarm)的規范和接口
  • cluster:集群管理的具體實現
  • storage:數據容器的具體實現
  • query:為前端提供的查詢接口的具體實現
  • receiver:接收探針上報數據的接收器的具體實現
  • alarm:監控告警的具體實現

以及一個可選組件:

  • telemetry:用于監控OAP自身的健康狀況

而前面提到的OAP的高擴展性則體現在核心業務的規范均定義在了core中,如果有需要自己擴展的,只需要自己單獨做自己的實現,而不需要做侵入式的改動,最典型的示例則是官方支持的storage,不僅支持單機demo的內存數據庫H2和經典的ES,連目前開源的Tidb都可以接入。

安裝
  1. 下載最新的安裝包
  2. 解壓,并進入bin目錄執行startup.sh啟動
  3. 訪問http://localhost:8080/ 即可看到面板
  4. 啟動服務
    添加如下VM 參數:
-javaagent:${agent_home}/agent/skywalking-agent.jar -Dskywalking.agent.service_name=${service_name}
image.png

【轉載請注明出處】:http://www.lxweimin.com/p/e1592d395891

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,646評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,595評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,560評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,035評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,814評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,224評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,301評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,444評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,988評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,804評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,998評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,544評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,237評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,665評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,927評論 1 287
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,706評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,993評論 2 374