能夠理解服務監控三要素 能夠理解常用的APM系統優勢差異 能夠基於IDEA集成Skywalking Agent 能基於生產環境使用Skywalking Agent 掌握Rocketbot 性能分析 鏈路追蹤 儀錶盤應用 Webhook 1 Skywalking概述 隨著互聯網架構的擴張,分散式系統變 ...
- 能夠理解服務監控三要素
- 能夠理解常用的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/
本文由傳智教育博學谷 - 狂野架構師教研團隊發佈
如果本文對您有幫助,歡迎關註和點贊;如果您有任何建議也可留言評論或私信,您的支持是我堅持創作的動力
轉載請註明出處!