在介紹調用鏈監控工具以前,咱們首先須要知道在微服務架構系統中常常會遇到兩個問題:html
通常來講要解決這兩個問題或者與之相似的問題,就須要用到調用鏈監控工具。那麼調用鏈監控工具是怎麼實現問題的快速定位的呢?這就須要咱們理解調用鏈監控的基礎實現原理,咱們來看一張圖:
java
圖中有兩個微服務分別是內容中心和用戶中心,其中內容中心的/shares/1
接口會調用用戶中心的/users/1
接口,這裏就產生了一個調用鏈。咱們能夠將調用的過程分爲四個階段或者說狀態,當內容中心發送調用請求時處於「client send」狀態,用戶中心接收到調用請求時處於「server receive」狀態,用戶中心處理完請求並返回結果時處於「server send」狀態,最後內容中心接收到響應結果時處於「client receive」狀態。linux
假設,調用鏈流轉每一個狀態時都會向一張數據表裏插入一些數據,以下圖所示:
git
表字段說明:github
這是一張典型的自表一對多的表結構,根據這張表的數據,就能夠實現對以上所提到的兩個問題進行快速定位。首先對於第一個問題,能夠經過查詢表內的數據行數,判斷調用鏈在哪一個階段中斷了。例如表中只有uuid1和uuid2兩條數據,就能夠判斷出是user-center的接口出現了問題,沒有正常返回結果。再如表中只有uuid一、uuid2及uuid3這三條數據,就能夠判斷出content-center沒有正常接收到user-center返回的結果,以此類推。如此一來,就能夠經過表中的數據快速定位出跨微服務的API調用是在哪一個階段發生了異常。web
對於第二個問題,能夠經過計算timestamp
分析哪一個調用比較耗時。例如上圖中的t2 - t1
能夠得出請求的發送到請求的接收所消耗的時間,再如t3 - t2
能夠得出/users/1
這個接口的調用耗時,而t4 - t1
則能夠得出整個調用鏈的耗時,以此類推。因此當跨微服務的API調用發生性能瓶頸時,就能夠經過分析各個調用接口的耗時,快速定位出是哪一個微服務接口拖慢了整個調用鏈耗時。spring
以上舉例簡述了實現調用鏈監控的基礎原理,雖然未必全部的調用鏈監控工具都是這麼實現的,但基本都殊途同歸,或在其之上進行了一些拓展。因此只要理解了這一部分,在學習各類調用鏈監控工具時就會比較快上手。docker
Spring Cloud Sleuth實現了一種分佈式的服務鏈路跟蹤解決方案,經過使用Sleuth可讓咱們快速定位某個服務的問題。簡單來講,Sleuth至關於調用鏈監控工具的客戶端,集成在各個微服務上,負責產生調用鏈監控數據。數據庫
官方文檔地址以下:api
一些概念:
Span(跨度):Span是基本的工做單元。Span包括一個64位的惟一ID,一個64位trace碼,描述信息,時間戳事件,key-value 註解(tags),span處理者的ID(一般爲IP)。
最開始的初始Span稱爲根span,此span中span id和 trace id值相同。
Trance(跟蹤):包含一系列的span,它們組成了一個樹型結構
若是一個服務的調用關係以下:
那麼此時將Span和Trace在一個系統中使用Zipkin註解的過程圖形化以下:
每一個顏色的代表一個span(總計7個spans,從A到G),每一個span有相似的信息
Trace Id = X Span Id = D Client Sent
此span表示span的Trance Id是X,Span Id是D,同時它發送一個Client Sent事件
spans 的parent/child關係圖形化以下:
瞭解完基本的一些概念後,咱們來在訂單服務和商品服務中,集成spring cloud sleuth以及zipkin。在兩個服務的pom.xml文件中,增長以下依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
爲了更詳細的查看服務通訊時的日誌信息,咱們能夠將Feign和Sleuth的日誌級別設置爲debug。在兩個項目的配置文件中,加入以下內容便可:
logging: level: org.springframework.cloud.openfeign: debug org.springframework.cloud.sleuth: debug
啓動訂單、商品服務項目,而後訪問建立訂單的接口,訂單服務的控制檯會輸出一段這樣的信息:
[order,6c8ecdeefb0fc723,cc4109a6e8e56d1c,false]
商品服務的控制檯也會輸出相似的信息,以下:
[product,6c8ecdeefb0fc723,40cdc34e745d59e7,false]
說明:
經過Sleuth產生的調用鏈監控信息,讓咱們能夠得知微服務之間的調用鏈路,可是監控信息只輸出到控制檯始終不太方便查看。因此咱們須要一個圖形化的工具,這時候就輪到zipkin出場了。Zipkin是Twitter開源的分佈式跟蹤系統,主要用來收集系統的時序數據,從而追蹤系統的調用問題。zipkin官網地址以下:
zipkin結構圖:
接下來咱們搭建一個zipkin服務器。
方式1,使用Zipkin官方的Shell下載,使用以下命令可下載最新版本:
[root@01server ~]# curl -sSL https://zipkin.io/quickstart.sh | bash -s
下載下來的文件名爲 zipkin.jar
方式2,到Maven中央倉庫下載,使用瀏覽器訪問以下地址便可:
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
下載下來的文件名爲 zipkin-server-{版本號}-exec.jar
因爲Zipkin實際是一個Spring Boot項目,因此使用以上兩種方式下載的jar包,能夠直接使用以下命令啓動:
java jar {zipkin jar包路徑}
方式3,經過docker安裝,命令以下:
[root@01server ~]# docker run -d -p 9411:9411 openzipkin/zipkin
安裝好後,使用瀏覽器訪問9411端口,主頁面以下所示:
而後在訂單服務中將以前的sleuth依賴替換成以下依賴:
<!-- 這個依賴包含了sleuth和zipkin --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
在配置文件中,增長zipkin相關的配置項。以下:
spring: ... zipkin: base-url: http://127.0.0.1:9411/ # zipkin服務器的地址 # 關閉服務發現,不然Spring Cloud會把zipkin的url當作服務名稱 discoveryClientEnabled: false sender: type: web # 設置使用http的方式傳輸數據 sleuth: sampler: probability: 1 # 設置抽樣採集率爲100%,默認爲0.1,即10%
配置好後重啓項目,並訪問建立訂單接口。下單成功後,到zipkin頁面上就能夠查看到order服務的鏈路信息了:
會有紅色的信息表示有錯誤,點擊上圖中的紅色信息後,能夠進入到服務鏈路的查看頁面,在這裏能夠看到整條服務鏈路,而且能夠看到每個服務調用的耗時,也能夠看到是哪一步調用發生了錯誤:
點擊每一行信息均可以查看其詳情信息,例如我點擊耗時46.236ms的那行信息,其詳細信息以下:
Zipkin默認是將監控數據存儲在內存的,若是Zipkin掛掉或重啓的話,那麼監控數據就會丟失。因此若是想要搭建生產可用的Zipkin,就須要實現監控數據的持久化。而想要實現數據持久化,天然就是得將數據存儲至數據庫。好在Zipkin支持將數據存儲至:
Zipkin數據持久化相關的官方文檔地址以下:
Zipkin支持的這幾種存儲方式中,內存顯然是不適用於生產的,這一點開始也說了。而使用MySQL的話,當數據量大時,查詢較爲緩慢,也不建議使用。Twitter官方使用的是Cassandra做爲Zipkin的存儲數據庫,但國內大規模用Cassandra的公司較少,並且Cassandra相關文檔也很少。
綜上,故採用Elasticsearch是個比較好的選擇,關於使用Elasticsearch做爲Zipkin的存儲數據庫的官方文檔以下:
既然選擇Elasticsearch做爲Zipkin的存儲數據庫,那麼天然首先須要搭建一個Elasticsearch服務,單節點搭建比較簡單,直接到官網下載壓縮包,而後使用以下命令解壓並啓動便可(關於ES的版本選擇需參考官方文檔,目前Zipkin支持5.x、6.x及7.x):
[root@01server ~]# tar -zxvf elasticsearch-6.5.3-linux-x86_64.tar.gz # 解壓 [root@01server ~]# cd elasticsearch-6.5.3/bin [root@01server ~/elasticsearch-6.5.3/bin]# ./elasticsearch # 啓動
因爲Elasticsearch不是本文的重點,這裏不作很少的介紹,關於Elasticsearch的集羣搭建能夠參考以下文章:
搭建好Elasticsearch後,使用以下命令啓動Zipkin,Zipkin就會切換存儲類型爲Elasticsearch,而後根據指定的鏈接地址鏈接Elasticsearch並存儲數據:
STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-server-2.11.3-exec.jar
Tips:
STORAGE_TYPE
和ES_HOSTS
是環境變量,STORAGE_TYPE
用於指定Zipkin的存儲類型是啥;而ES_HOSTS
則用於指定Elasticsearch地址列表,有多個節點時使用逗號( ,
)分隔。除此以外,還能夠指定其餘環境變量,參考下表:
關於其餘環境變量,可參考官方文檔:
最後能夠根據如下測試步驟,自行測試一下Zipkin是否能正常將監控數據持久化存儲:
在上一小節中,簡單介紹了Zipkin的數據持久化,並整合了Elasticsearch做爲Zipkin的存儲數據庫。但此時會有一個問題,就是Zipkin在整合Elasticsearch後會沒法分析服務之間的依賴關係圖,由於此時數據都存儲到Elasticsearch中了,沒法再像以前那樣在內存中進行分析。
想要解決這個問題,須要下載並使用Zipkin的一個子項目:
方式1,使用官方的Shell下載,使用以下命令可下載最新版本:
[root@01server ~]# curl -sSL https://zipkin.io/quickstart.sh | bash -s io.zipkin.dependencies:zipkin-dependencies:LATEST zipkin-dependencies.jar
下載下來的文件名爲 zipkin-dependencies.jar
方式2,到Maven中央倉庫下載,使用瀏覽器訪問以下地址便可:
https://search.maven.org/remote_content?g=io.zipkin.dependencies&a=zipkin-dependencies&v=LATEST
下載下來的文件名爲 zipkin-dependencies-{版本號}.jar
下載好後,使用以下命令運行這個jar包便可分析Elasticsearch中存儲的數據:
[root@01server ~]# STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-dependencies-2.3.2.jar
該jar包運行結束後,到Zipkin的界面上點開「Dependencies」就能夠正常查看到依賴關係圖了。
方式3,經過docker下載並運行,命令以下:
[root@01server ~]# docker run --env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.190.129:9200 openzipkin/zipkin-dependencies
Tips:
這個Zipkin Dependencies屬因而一個job,不是服務,即不會持續運行,而是每運行一次才分析數據。若想持續運行的話,須要本身寫個定時腳原本定時運行這個job
使用Elasticsearch時Zipkin Dependencies支持的環境變量:
Zipkin Dependencies支持的其餘環境變量:
Zipkin Dependencies默認分析的是當天的數據,能夠經過以下命令讓Zipkin Dependencies分析指定日期的數據: