- 能夠理解服務監控三要素
- 能夠理解常用的APM系統優勢差異
- 能夠基于IDEA集成Skywalking Agent
- 能基于生產環境使用Skywalking Agent
- 掌握Rocketbot
- 性能分析
- 鏈路追蹤
- 儀表盤應用
- Webhook
1 Skywalking概述

隨著互聯網架構的擴張,分布式系統變得日趨復雜,越來越多的組件開始走向分布式化,如微服務、訊息收發、分布式資料庫、分布式快取、分布式物件存盤、跨域呼叫,這些組件共同構成了繁雜的分布式網路,
我們思考下這些問題:
1:一個請求經過了這些服務后其中出現了一個呼叫失敗的問題,如何定位問題發生的地方?
2:如何計算每個節點訪問流量?
3:流量波動的時候,增加哪些節點集群服務?
這些問題要想得到解決,一定是有資料支撐,絕不是靠開發人員或者運維人員的直覺,為了解決分布式應用、微服務系統面臨的這些挑戰,APM系統營運而生,
1.1 微服務系統監控三要素

- Logging 就是記錄系統行為的離散事件,例如,服務在處理某個請求時列印的錯誤日志,我們可以將這些日志資訊記錄到 ElasticSearch 或是其他存盤中,然后通過 Kibana 或是其他工具來分析這些日志了解服務的行為和狀態,大多數情況下,日志記錄的資料很分散,并且相互獨立,比如錯誤日志、請求處理程序中關鍵步驟的日志等等,
- Metrics 是系統在一段時間內某一方面的某個度量,可聚合的資料,且通常是固定型別的時序資料,例如,電商系統在一分鐘內的請求次數,我們常見的監控系統中記錄的資料都屬于這個范疇,例如 Promethus、Open-Falcon 等,這些監控系統最終給運維人員展示的是一張張二維的折線圖,Metrics 是可以聚合的,例如,為電商系統中每個 HTTP 介面添加一個計數器,計算每個介面的 QPS,之后我們就可以通過簡單的加和計算得到系統的總負載情況,
- Tracing 即我們常說的分布式鏈路追蹤,記錄單個請求的處理流程,其中包括服務呼叫和處理時長等資訊,在微服務架構系統中一個請求會經過很多服務處理,呼叫鏈路會非常長,要確定中間哪個服務出現例外是非常麻煩的一件事,通過分布式鏈路追蹤,運維人員就可以構建一個請求的視圖,這個視圖上展示了一個請求從進入系統開始到回傳回應的整個流程,這樣,就可以從中了解到所有服務的例外情況、網路呼叫,以及系統的性能瓶頸等,
1.2 什么是鏈路追蹤
谷歌在 2010 年 4 月發表了一篇論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》介紹了分布式追蹤的概念,之后很多互聯網公司都開始根據這篇論文打造自己的分布式鏈路追蹤系統,APM 系統的核心技術就是分布式鏈路追蹤,
論文在線地址:https://storage.googleapis.com/pub-tools-public-publication-data/pdf/36356.pdf,
國內的翻譯版:https://bigbully.github.io/Dapper-translation/
在此文中闡述了Google在生產環境下對于分布式鏈路追蹤系統Drapper的設計思路與使用經驗,隨后各大廠商基于這篇論文都開始自研自家的分布式鏈路追蹤產品,如阿里的Eagle eye(鷹眼)、zipkin,京東的“Hydra”、大眾點評的“CAT”、新浪的“Watchman”、唯品會的“Microscope”、窩窩網的“Tracing”都是基于這片文章的設計思路而實作的,所以要學習分布式鏈路追蹤,對于Dapper論文的理解至關重要,
但是也帶來了新的問題:各家的分布式追蹤方案是互不兼容的,這才誕生了 OpenTracing,
OpenTracing 是一個 Library,定義了一套通用的資料上報介面,要求各個分布式追蹤系統都來實作這套介面,這樣一來,應用程式只需要對接 OpenTracing,而無需關心后端采用的到底什么分布式追蹤系統,因此開發者可以無縫切換分布式追蹤系統,也使得在通用代碼庫增加對分布式追蹤的支持成為可能,
OpenTracing 于 2016 年 10 月加入 CNCF 基金會,是繼 Kubernetes 和 Prometheus 之后,第三個加入CNCF 的開源專案,它是一個中立的(廠商無關、平臺無關)分布式追蹤的 API 規范,提供統一介面,可方便開發者在自己的服務中集成一種或多種分布式追蹤的實作,

OpenTracing API 目前支持的語言眾多:

目前,主流的分布式追蹤實作基本都已經支持 OpenTracing,
1.2.1 鏈路追蹤
下面通過官方的一個示例簡單介紹說明什么是 Tracing,把Tracing學完后,更有助于大家運用Skywalking UI進行資料分析,
在一個分布式系統中,追蹤一個事務或者呼叫流程,可以用下圖方式描繪出來,這類流程圖可以看清各組件的組合關系,但它并不能看出一次呼叫觸發了哪個組件呼叫、什么時間呼叫、是串行呼叫還是并行呼叫,

一種更有效的展現方式就是下圖這樣,這是一個典型的 trace 視圖,這種展現方式增加顯示了執行時間的背景關系,相關服務間的層次關系,行程或者任務的串行或并行呼叫關系,這樣的視圖有助于發現系統呼叫的關鍵路徑,通過關注關鍵路徑的執行程序,開發團隊就可以專注于優化路徑中的關鍵服務,最大幅度的提升系統性能,例如下圖中,我們可以看到請求串行的呼叫了授權服務、訂單服務以及資源服務,在資源服務中又并行的執行了三個子任務,我們還可以看到,在這整個請求的生命周期中,資源服務耗時是最長的,

分布式追蹤系統的原理:
分布式追蹤系統大體分為三個部分,資料采集、資料持久化、資料展示,資料采集是指在代碼中埋點,設定請求中要上報的階段,以及設定當前記錄的階段隸屬于哪個上級階段,資料持久化則是指將上報的資料落盤存盤,資料展示則是前端查詢與之關聯的請求階段,并在界面上呈現,
上圖是一個請求的流程例子,請求從客戶端發出,到達負載均衡,再依次進行認證、計費,最后取到目標資源,請求程序被采集之后,會以上圖的形式呈現,橫坐標是時間,圓角矩形是請求的執行的各個階段
1.2.2 OpenTracing
學好OpenTracing,更有助于我們運用Skywalking ,
1、資料模型:
這部分在 OpenTracing 的規范中寫的非常清楚,下面只大概翻譯一下其中的關鍵部分,細節可參考原始檔案 《The OpenTracing Semantic Specification》,
Causal relationships between Spans in a single Trace
解釋了Trace 和 Span的因果關系
[Span A] ←←←(the root span)
|
+------+------+
| |
[Span B] [Span C] ←←←(Span C is a `ChildOf` Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
↑
↑
↑
(Span G `FollowsFrom` Span F)
Trace
一個 Trace 代表一個事務、請求或是流程在分布式系統中的執行程序,OpenTracing 中的一條 Trace呼叫鏈,由多個 Span 組成,一個 Span 代表系統中具有開始時間和執行時長的邏輯單元,Span 一般會有一個名稱,一條 Trace 中 Span 是首尾連接的,
Span
Span 代表系統中具有開始時間和執行時長的邏輯單元,Span 之間通過嵌套或者順序排列建立邏輯因果關系,
如果按時間關系呈現的話如下所示:
––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–––––––|–> time
[Span A···················································]
[Span B··············································]
[Span D··········································]
[Span C········································]
[Span E·······] [Span F··] [Span G··] [Span H··]
每個 Span 中可以包含以下的資訊:
- 操作名稱:例如訪問的具體 RPC 服務,訪問的 URL 地址等;
- 起始時間;2021-1-25 22:00:00
- 結束時間;2021-1-30 22:00:00
- Span Tag:一組鍵值對(k-v)構成的Span標簽集合,其中鍵必須為字串型別,值可以是字串、bool 值或者數字;
- Span Log:一組 Span 的日志集合;
- SpanContext:Trace 的全域背景關系資訊;
- References:Span 之間的參考關系,下面詳細說明 Span 之間的參考關系;
在一個 Trace 中,一個 Span 可以和一個或者多個 Span 間存在因果關系,目前,OpenTracing 定義了 ChildOf 和 FollowsFrom 兩種 Span 之間的參考關系,這兩種參考型別代表了子節點和父節點間的直接因果關系,
-
ChildOf 關系:一個 Span 可能是一個父級 Span 的孩子,即為 ChildOf 關系,下面這些情況會構成 ChildOf 關系:
-
一個 HTTP 請求之中,被呼叫的服務端產生的 Span,與發起呼叫的客戶端產生的 Span,就構成了 ChildOf 關系;
-
一個 SQL Insert 操作的 Span,和 ORM 的 save 方法的 Span 構成 ChildOf 關系,
-
很明顯,上述 ChildOf 關系中的父級 Span 都要等待子 Span 的回傳,子 Span 的執行時間影響了其所在父級 Span 的執行時間,父級 Span 依賴子 Span 的執行結果,除了串行的任務之外,我們的邏輯中還有很多并行的任務,它們對應的 Span 也是并行的,這種情況下一個父級 Span 可以合并所有子 Span 的執行結果并等待所有并行子 Span 結束,
FollowsFrom 關系:表示跟隨關系,意為在某個階段之后發生了另一個階段,用來描述順序執行關系
Logs
每個 Span 可以進行多次 Logs 操作,每一次 Logs 操作,都需要帶一個時間戳,以及一個可選的附加資訊,
Tags
每個 Span 可以有多個鍵值對形式的 Tags,Tags 是沒有時間戳的,只是為 Span 添加一些簡單解釋和補充資訊,
SpanContext 和 Baggage
SpanContext 表示行程邊界,在跨進呼叫時需要將一些全域資訊,例如,TraceId、當前 SpanId 等資訊封裝到 Baggage 中傳遞到另一個行程(下游系統)中,
Baggage 是存盤在 SpanContext 中的一個鍵值對集合,它會在一條 Trace 中全域傳輸,該 Trace 中的所有 Span 都可以獲取到其中的資訊,
需要注意的是,由于 Baggage 需要跨行程全域傳輸,就會涉及相關資料的序列化和反序列化操作,如果在 Baggage 中存放過多的資料,就會導致序列化和反序列化操作耗時變長,使整個系統的 RPC 的延遲增加、吞吐量下降,
雖然 Baggage 與 Span Tags 一樣,都是鍵值對集合,但兩者最大區別在于 Span Tags 中的資訊不會跨行程傳輸,而 Baggage 需要全域傳輸,因此,OpenTracing 要求實作提供 Inject 和 Extract 兩種操作,SpanContext 可以通過 Inject 操作向 Baggage 中添加鍵值對資料,通過 Extract 從 Baggage 中獲取鍵值對資料,
2、核心介面語意
OpenTracing 希望各個實作平臺能夠根據上述的核心概念來建模實作,不僅如此,OpenTracing 還提供了核心介面的描述,幫助開發人員更好的實作 OpenTracing 規范,
- Span 介面
Span介面必須實作以下的功能:
-
- 獲取關聯的 SpanContext:通過 Span 獲取關聯的 SpanContext 物件,
- 關閉(Finish)Span:完成已經開始的 Span,
- 添加 Span Tag:為 Span 添加 Tag 鍵值對,
- 添加 Log:為 Span 增加一個 Log 事件,
- 添加 Baggage Item:向 Baggage 中添加一組鍵值對,
- 獲取 Baggage Item:根據 Key 獲取 Baggage 中的元素,
-
SpanContext 介面
SpanContext 介面必須實作以下功能,用戶可以通過 Span 實體或者 Tracer 的 Extract 能力獲取 SpanContext 介面實體,
-
Tracer 介面
Tracer 介面必須實作以下功能:
-
創建 Span:創建新的 Span,
-
注入 SpanContext:主要是將跨行程呼叫攜帶的 Baggage 資料記錄到當前 SpanContext 中,
-
提取 SpanContext ,主要是將當前 SpanContext 中的全域資訊提取出來,封裝成 Baggage 用于后續的跨行程呼叫,
1.3 常見APM系統
我們前面提到了APM系統,APM 系統(Application Performance Management,即應用性能管理)是對企業的應用系統進行實時監控,實作對應用性能管理和故障定位的系統化解決方案,在運維中常用,
- CAT(開源): 由國內美團點評開源的,基于 Java 語言開發,目前提供 Java、C/C++、Node.js、Python、Go 等語言的客戶端,監控資料會全量統計,國內很多公司在用,例如美團點評、攜程、拼多多等,CAT 需要開發人員手動在應用程式中埋點,對代碼侵入性比較強,
- Zipkin(開源): 由 Twitter 公司開發并開源,Java 語言實作,侵入性相對于 CAT 要低一點,需要對web.xml 等相關組態檔進行修改,但依然對系統有一定的侵入性,Zipkin 可以輕松與 Spring Cloud 進行集成,也是 Spring Cloud 推薦的 APM 系統,
- Pinpoint(開源): 韓國團隊開源的 APM 產品,運用了位元組碼增強技術,只需要在啟動時添加啟動引數即可實作 APM 功能,對代碼無侵入,目前支持 Java 和 PHP 語言,底層采用 HBase 來存盤資料,探針收集的資料粒度非常細,但性能損耗較大,因其出現的時間較長,完成度也很高,檔案也較為豐富,應用的公司較多,
- SkyWalking(開源): 國人開源的產品,2019 年 4 月 17 日 SkyWalking 從 Apache 基金會的范訓器畢業成為頂級專案,目前 SkyWalking 支持 Java、.Net、Node.js 等探針,資料存盤支持MySQL、ElasticSearch等,
- 還有很多不開源的 APM 系統,例如,淘寶鷹眼、Google Dapper 等等,
我們將學習Skywalking,Skywalking有很多優秀特性,SkyWalking 對業務代碼無侵入,性能表現優秀,SkyWalking 增長勢頭強勁,社區活躍,中文檔案齊全,支持多語言探針, SkyWalking 支持Dubbo、gRPC、SOFARPC 等很多框架,
1.4 Skywalking介紹
2015年由個人吳晟(華為開發者)主導開源,作者是華為開發云監控產品經理,主導監控產品的規劃、技術路線及相關研發作業,也是OpenTracing分布式追蹤標準組織成員 ,該專案 2017年加入Apache范訓器,是一個分布式系統的應用程式性能監控工具(APM),專為微服務、云原生架構和基于容器(Docker、K8s、Mesos)架構而設計,
官方站點:http://skywalking.apache.org/
GitHub專案地址:https://github.com/apache/skywalking

Skywalking是一個可觀測性分析平臺和應用性能管理系統,它也是基于OpenTracing規范、開源的AMP系統,Skywalking提供分布式跟蹤、服務網格遙測分析、度量聚合和可視化一體化解決方案,支持Java, .Net Core, PHP, NodeJS, Golang, LUA, c++代理,支持Istio +特使服務網格
我們在學習Skywalking之前,可以先訪問官方提供的控制臺演示
演示地址:http://demo.skywalking.apache.org/ 賬號:skywalking 密碼:skywalking

1、SkyWalking 核心功能:
-
指標分析:服務,實體,端點指標分析
-
問題分析:在運行時分析代碼,找到問題的根本原因
-
服務拓撲:提供服務的拓撲圖分析
-
依賴分析:服務實體和端點依賴性分析
-
服務檢測:檢測慢速的服務和端點
-
性能優化:根據服務監控的結果提供性能優化的思路
-
鏈路追蹤:分布式跟蹤和背景關系傳播
-
資料庫監控:資料庫訪問指標監控統計,檢測慢速資料庫訪問陳述句(包括SQL陳述句)
-
服務告警:服務告警功能
名詞解釋:
-
服務(service):業務資源應用系統
-
端點(endpoint):應用系統對外暴露的功能介面
-
實體(instance):物理機

-
2、SkyWalking 特點:
- 多語言自動探針,支持 Java、.NET Code 等多種語言,
- 為多種開源專案提供了插件,為 Tomcat、 HttpClient、Spring、RabbitMQ、MySQL 等常見基礎設施和組件提供了自動探針,
- 微內核 + 插件的架構,存盤、集群管理、使用插件集合都可以進行自由選擇,
- 支持告警,
- 優秀的可視化效果,
3、Skywalking架構圖:

skyWalking整體可分為:客戶端,服務端
客戶端:agent組件
? 基于探針技術采集服務相關資訊(包括跟蹤資料和統計資料),然后將采集到的資料上報給skywalking的資料收集器
服務端:又分為OAP,Storage,WebUI
-
OAP:observability analysis platform可觀測性分析平臺,負責接收客戶端上報的資料,對資料進行分析,聚合,計算后將資料進行存盤,并且還會提供一些查詢API進行資料的查詢,這個模塊其實就是我們所說的鏈路追蹤系統的Collector收集器
-
Storage:skyWalking的存盤介質,默認是采用H2,同時支持許多其他的存盤介質,比如:ElastaticSearch,mysql等
-
WebUI:提供一些圖形化界面展示對應的跟蹤資料,指標資料等等
2 Skywalking安裝
Skywalking資料存盤方式有2種,分別為H2(記憶體)和elasticsearch,如果資料量比較大,建議使用后者,作業中也建議使用后者,
Skywalking自身提供了UI管理控制臺,我們安裝的組件:
1:elasticsearch,建議使用elasticsearch7.x
2:elasticsearch-hq,elasticsearch的管理工具,更方便管理elasticsearch
3:Skywalking
4:Skywalking-UI
2.1 elasticsearch安裝
1)系統資源配置修改
elasticsearch占用系統資源比較大,我們需要修改下系統資源配置,這樣才能很好的運行elasticsearch,修改虛擬機配置,vi /etc/security/limits.conf ,追加內容:
* soft nofile 65536
* hard nofile 65536
修改vi /etc/sysctl.conf,追加內容 :
vm.max_map_count=655360
讓配置立即生效:
/sbin/sysctl -p
2)安裝elasticsearch
建議安裝:elasticsearch7.x,我們這里選擇7.6.2,并且采用容器的安裝方式,安裝如下:
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 --restart=always -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms84m -Xmx512m" -d elasticsearch:7.6.2
3)elasticsearch跨域配置
elasticsearch默認是沒有開啟跨域,我們需要配置跨域,并配置集群節點名字:
#進入容器
docker exec -it elasticsearch /bin/bash
修改容器中/usr/share/elasticsearch/config/elasticsearch.yml檔案,添加配置如下:
cluster.name: "elasticsearch"
http.cors.enabled: true
http.cors.allow-origin: "*"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
引數說明:
cluster.name:集群服務名字
http.cors.enabled:開啟跨域
http.cors.allow-origin: 允許跨域域名,*代表所有域名
network.host: 外部訪問的IP
discovery.zen.minimum_master_nodes: 最小主節點個數
安裝完成后,重啟容器docker restart elasticsearch,再訪問http://192.168.200.129:9200/效果如下:

安裝 ElasticSearch管理界面elasticsearch-hq
docker run -d --name elastic-hq -p 5000:5000 --restart always elastichq/elasticsearch-hq
安裝完成后,訪問控制臺地址 http://192.168.200.129:5000/#!/clusters/elasticsearch

2.2 Skywalking安裝
Skywalking的安裝我們也采用Docker安裝方式,同時我們需要為Skywalking指定存盤服務:
#安裝Skywalking
docker run --name skywalking -d -p 1234:1234 -p 11800:11800 -p 12800:12800 --restart always --link elasticsearch:elasticsearch -e SW_STORAGE=elasticsearch7 -e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200 apache/skywalking-oap-server
引數說明:
--link elasticsearch:elasticsearch:存盤服務使用elasticsearch
-e SW_STORAGE=elasticsearch7:存盤服務elasticsearch的版本
-e SW_STORAGE_ES_CLUSTER_NODES=elasticsearch:9200:存盤服務elasticsearch的鏈接地址
接下來安裝Skywalking-UI,需要指定Skywalking服務名字:
docker run --name skywalking-ui -d -p 8080:8080 --link skywalking:skywalking -e SW_OAP_ADDRESS=skywalking:12800 --restart always apache/skywalking-ui
安裝完成后,我們接下來訪問Skywalking控制臺:http://192.168.200.129:8080

關于SkywalkingUI的使用,我們在下一節知識點詳細講解,
2.3 Skywalking生產環境問題
1)ES分片數量上限
如果此時訪問http://192.168.200.129:8080/ 出現500錯誤,錯誤如下,此時其實是Elasticsearch出了問題:
"com.netflix.zuul.exception.ZuulException","message":"GENERAL"
我們可以查看skywalking的日志docker logs --since 30m skywalking,會報如下錯誤:
Failed: 1: this action would add [2] total shards, but this cluster currently has [1000]/[1000] maximum shards open;]
這種錯誤一般是生產環境中Elasticsearch分片數量達到了峰值,es集群的默認最大分片數是1000,我們需要調整Elasticsearch的默認分片數量,修改方式有多種,最常用的是直接修改elasticsearch.yml組態檔:
#進入elasticsearch容器
docker exec -it elasticsearch /bin/bash
#編輯
vi /usr/share/elasticsearch/config/elasticsearch.yml
#添加如下配置
cluster.max_shards_per_node: 10000000
保存配置后,記得洗掉data/nodes資料包,再重啟elasticsearch,此時就可以正常訪問了,
2)磁盤清理
如果此時能打開skywalking-ui界面,但是沒有資料,則需要清理磁盤空間,可能是磁盤空間滿了,如果是docker容器,可以使用docker system prune命令實作清理,docker system prune命令可以用于清理磁盤,洗掉關閉的容器、無用的資料卷和網路,以及dangling鏡像(即無tag的鏡像),docker system prune -a命令清理得更加徹底,可以將沒有容器使用Docker鏡像都刪掉,
2.4 docker-compose部署
創建docker-compose.yml并配置如下
version: '3.3'
services:
elasticsearch:
image: elasticsearch:7.6.2
container_name: elasticsearch
restart: always
privileged: true
hostname: elasticsearch
ports:
- 9200:9200
- 9300:9300
environment:
- discovery.type=single-node
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- TZ=Asia/Shanghai
networks:
- skywalking
ulimits:
memlock:
soft: -1
hard: -1
elasticsearch-hq:
image: elastichq/elasticsearch-hq
container_name: elasticsearch-hq
restart: always
privileged: true
hostname: elasticsearch-hq
ports:
- 5000:5000
environment:
- TZ=Asia/Shanghai
networks:
- skywalking
oap:
image: apache/skywalking-oap-server:8.3.0-es7
container_name: oap
hostname: oap
privileged: true
depends_on:
- elasticsearch
links:
- elasticsearch
restart: always
ports:
- 11800:11800
- 12800:12800
environment:
SW_STORAGE: elasticsearch7
SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
TZ: Asia/Shanghai
volumes:
- ./config/alarm-settings.yml:/skywalking/config/alarm-settings.yml
networks:
- skywalking
ui:
image: apache/skywalking-ui:8.3.0
container_name: ui
privileged: true
depends_on:
- oap
links:
- oap
restart: always
ports:
- 8080:8080
environment:
SW_OAP_ADDRESS: oap:12800
TZ: Asia/Shanghai
networks:
- skywalking
networks:
skywalking:
driver: bridge
通過命令一鍵啟動:
docker-compose up -d
啟動成功后訪問skywalking的webui頁面:http://192.168.200.129:8080/
本文由傳智教育博學谷 - 狂野架構師教研團隊發布
如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支持是我堅持創作的動力
轉載請注明出處!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/491827.html
標籤:Java
