sleuth:英 [slu:θ] 美 [sluθ] n.足跡,警犬,偵探vi.作偵探html
微服務架構是一個分佈式架構,它按業務劃分服務單元,一個分佈式系統每每有不少個服務單元。因爲服務單元數量衆多,業務的複雜性,若是出現了錯誤和異常,很難去定位。主要體如今,一個請求可能須要調用不少個服務,而內部服務的調用複雜性,決定了問題難以定位。因此微服務架構中,必須實現分佈式鏈路追蹤,去跟進一個請求到底有哪些服務參與,參與的順序又是怎樣的,從而達到每一個請求的步驟清晰可見,出了問題,很快定位。前端
舉幾個例子:java
一、在微服務系統中,一個來自用戶的請求,請求先達到前端A(如前端界面),而後經過遠程調用,達到系統的中間件B、C(如負載均衡、網關等),最後達到後端服務D、E,後端通過一系列的業務邏輯計算最後將數據返回給用戶。對於這樣一個請求,經歷了這麼多個服務,怎麼樣將它的請求過程的數據記錄下來呢?這就須要用到服務鏈路追蹤。mysql
二、分析微服務系統在大壓力下的可用性和性能。git
Zipkin能夠結合壓力測試工具一塊兒使用,分析系統在大壓力下的可用性和性能。github
設想這麼一種狀況,若是你的微服務數量逐漸增大,服務間的依賴關係愈來愈複雜,怎麼分析它們之間的調用關係及相互的影響?web
spring boot對zipkin的自動配置可使得全部RequestMapping匹配到的endpoints獲得監控,以及強化了RestTemplate,對其加了一層攔截器,使得由它發起的http請求也一樣被監控。redis
Google開源的 Dapper鏈路追蹤組件,並在2010年發表了論文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,這篇文章是業內實現鏈路追蹤的標杆和理論基礎,具備很是大的參考價值。spring
目前,鏈路追蹤組件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鷹眼)等,它們都是很是優秀的鏈路追蹤開源組件。sql
本文主要講述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin很是的簡單,只須要引入相應的依賴和作相關的配置便可。
Spring Cloud Sleuth 主要功能就是在分佈式系統中提供追蹤解決方案,而且兼容支持了 zipkin,你只須要在pom文件中引入相應的依賴便可。
微服務架構上經過業務來劃分服務的,經過REST調用,對外暴露的一個接口,可能須要不少個服務協同才能完成這個接口功能,若是鏈路上任何一個服務出現問題或者網絡超時,都會造成致使接口調用失敗。隨着業務的不斷擴張,服務之間互相調用會愈來愈複雜。
隨着服務的愈來愈多,對調用鏈的分析會愈來愈複雜。它們之間的調用關係也許以下:
Spring Cloud Sleuth採用的是Google的開源項目Dapper的專業術語。
將Span和Trace在一個系統中使用Zipkin註解的過程圖形化:
spring cloud提供了spring-cloud-sleuth-zipkin來方便集成zipkin實現(指的是Zipkin Client,而不是Zipkin服務器),該jar包能夠經過spring-cloud-starter-zipkin依賴來引入。
Zipkin是什麼
Zipkin分佈式跟蹤系統;它能夠幫助收集時間數據,解決在microservice架構下的延遲問題;它管理這些數據的收集和查找;Zipkin的設計是基於谷歌的Google Dapper論文。
每一個應用程序向Zipkin報告定時數據,Zipkin UI呈現了一個依賴圖表來展現多少跟蹤請求通過了每一個應用程序;若是想解決延遲問題,能夠過濾或者排序全部的跟蹤請求,而且能夠查看每一個跟蹤請求佔總跟蹤時間的百分比。
爲何使用Zipkin
隨着業務愈來愈複雜,系統也隨之進行各類拆分,特別是隨着微服務架構和容器技術的興起,看似簡單的一個應用,後臺可能有幾十個甚至幾百個服務在支撐;一個前端的請求可能須要屢次的服務調用最後才能完成;當請求變慢或者不可用時,咱們沒法得知是哪一個後臺服務引發的,這時就須要解決如何快速定位服務故障點,Zipkin分佈式跟蹤系統就能很好的解決這樣的問題。
針對服務化應用全鏈路追蹤的問題,Google發表了Dapper論文,介紹了他們如何進行服務追蹤分析。其基本思路是在服務調用的請求和響應中加入ID,標明上下游請求的關係。利用這些信息,能夠可視化地分析服務調用鏈路和服務間的依賴關係。
對應Dpper的開源實現是Zipkin,支持多種語言包括JavaScript,Python,Java, Scala, Ruby, C#, Go等。其中Java由多種不一樣的庫來支持
Spring Cloud Sleuth是對Zipkin的一個封裝,對於Span、Trace等信息的生成、接入HTTP Request,以及向Zipkin Server發送採集信息等所有自動完成。Spring Cloud Sleuth的概念圖見上圖。
跟蹤器(Tracer)位於你的應用程序中,並記錄發生的操做的時間和元數據,提供了相應的類庫,對用戶的使用來講是透明的,收集的跟蹤數據稱爲Span;將數據發送到Zipkin的儀器化應用程序中的組件稱爲Reporter,Reporter經過幾種傳輸方式之一將追蹤數據發送到Zipkin收集器(collector),而後將跟蹤數據進行存儲(storage),由API查詢存儲以向UI提供數據。
架構圖以下:
1.Trace
Zipkin使用Trace結構表示對一次請求的跟蹤,一次請求可能由後臺的若干服務負責處理,每一個服務的處理是一個Span,Span之間有依賴關係,Trace就是樹結構的Span集合;
2.Span
每一個服務的處理跟蹤是一個Span,能夠理解爲一個基本的工做單元,包含了一些描述信息:id,parentId,name,timestamp,duration,annotations等,例如:
{ "traceId": "bd7a977555f6b982", "name": "get-traces", "id": "ebf33e1a81dc6f71", "parentId": "bd7a977555f6b982", "timestamp": 1458702548478000, "duration": 354374, "annotations": [ { "endpoint": { "serviceName": "zipkin-query", "ipv4": "192.168.1.2", "port": 9411 }, "timestamp": 1458702548786000, "value": "cs" } ], "binaryAnnotations": [ { "key": "lc", "value": "JDBCSpanStore", "endpoint": { "serviceName": "zipkin-query", "ipv4": "192.168.1.2", "port": 9411 } } ] }
traceId:標記一次請求的跟蹤,相關的Spans都有相同的traceId;
id:span id;
name:span的名稱,通常是接口方法的名稱;
parentId:可選的id,當前Span的父Span id,經過parentId來保證Span之間的依賴關係,若是沒有parentId,表示當前Span爲根Span;
timestamp:Span建立時的時間戳,使用的單位是微秒(而不是毫秒),全部時間戳都有錯誤,包括主機之間的時鐘誤差以及時間服務從新設置時鐘的可能性,出於這個緣由,Span應儘量記錄其duration;
duration:持續時間使用的單位是微秒(而不是毫秒);
annotations:註釋用於及時記錄事件;有一組核心註釋用於定義RPC請求的開始和結束;
cs:Client Send,客戶端發起請求;
sr:Server Receive,服務器接受請求,開始處理;
ss:Server Send,服務器完成處理,給客戶端應答;
cr:Client Receive,客戶端接受應答從服務器;
binaryAnnotations:二進制註釋,旨在提供有關RPC的額外信息。
3.Transport
收集的Spans必須從被追蹤的服務運輸到Zipkin collector,有三個主要的傳輸方式:HTTP, Kafka和Scribe;
4.Components
有4個組件組成Zipkin:collector,storage,search,web UI
collector:一旦跟蹤數據到達Zipkin collector守護進程,它將被驗證,存儲和索引,以供Zipkin收集器查找;
storage:Zipkin最初數據存儲在Cassandra上,由於Cassandra是可擴展的,具備靈活的模式,並在Twitter中大量使用;可是這個組件可插入,除了Cassandra以外,還支持ElasticSearch和MySQL; 存儲,zipkin默認的存儲方式爲in-memory,即不會進行持久化操做。若是想進行收集數據的持久化,能夠存儲數據在Cassandra,由於Cassandra是可擴展的,有一個靈活的模式,而且在Twitter中被大量使用,咱們使這個組件可插入。除了Cassandra,咱們原生支持ElasticSearch和MySQL。其餘後端可能做爲第三方擴展提供。
search:一旦數據被存儲和索引,咱們須要一種方法來提取它。查詢守護進程提供了一個簡單的JSON API來查找和檢索跟蹤,主要給Web UI使用;
web UI:建立了一個GUI,爲查看痕跡提供了一個很好的界面;Web UI提供了一種基於服務,時間和註釋查看跟蹤的方法。
Zipkin下載和啓動
有三種安裝方法:
Zipkin的使用比較簡單,官網有說明幾種方式:
一、容器 Docker Zipkin
項目可以創建docker
鏡像,提供腳本和docker-compose.yml
來啓動預構建的圖像。最快的開始是直接運行最新鏡像:
docker run -d -p 9411:9411 openzipkin/zipkin
二、下載jar
若是你有java 8或更高版本,上手最快的方法是把新版本做爲一個獨立的可執行jar,Zipkin使用springboot來構建的:
curl -sSL https://zipkin.io/quickstart.sh | bash -s java -jar zipkin.jar
三、下載源代碼運行 Zipkin
能夠從源運行,若是你正在開發新的功能。要實現這一點,須要獲取Zipkin的源代碼並構建它。
# get the latest source git clone https://github.com/openzipkin/zipkin cd zipkin # Build the server and also make its dependencies ./mvnw -DskipTests --also-make -pl zipkin-server clean install # Run the server java -jar ./zipkin-server/target/zipkin-server-*exec.jar
一、使用官網本身打包好的Jar運行,Docker方式或下載源代碼本身打包Jar運行(由於zipkin使用了springboot,內置了服務器,因此能夠直接使用jar運行)。zipkin推薦使用docker方式運行,我後面會專門寫一遍關於docker的運行方式,而源碼運行方式好處是有機會體驗到最新的功能特性,可是可能也會帶來一些比較詭異的坑,因此不作講解,下面我直接是使用官網打包的jar運行過程:
官方提供了三種方式來啓動,這裏使用第二種方式來啓動;
wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec' java -jar zipkin.jar
首先下載zipkin.jar,我下載的是zipkin-server-2.10.2-exec.jar,而後直接使用-jar命令運行,要求jdk8以上版本;
D:\workspace\zipkin>java -jar zipkin-server-2.10.2-exec.jar
********
** **
* *
** **
** **
** **
** **
********
****
****
**** ****
****** **** ***
****************************************************************************
******* **** ***
**** ****
**
**
***** ** ***** ** ** ** ** **
** ** ** * *** ** **** **
** ** ***** **** ** ** ***
****** ** ** ** ** ** ** **
:: Powered by Spring Boot :: (v2.0.3.RELEASE)
...
2018-07-20 14:59:08.635 INFO 17284 --- [ main] o.xnio : XNIO version 3.3.8.Final
2018-07-20 14:59:08.650 INFO 17284 --- [ main] o.x.nio : XNIO NIO Implementation Version 3.3.8.Final
2018-07-20 14:59:08.727 INFO 17284 --- [ main] o.s.b.w.e.u.UndertowServletWebServer : Undertow started on port(s) 9411 (http) with context path ''
2018-07-20 14:59:08.729 INFO 17284 --- [ main] z.s.ZipkinServer : Started ZipkinServer in 4.513 seconds (JVM running for 5.756)
2018-07-20 14:59:36.546 INFO 17284 --- [ XNIO-1 task-1] i.u.servlet : Initializing Spring FrameworkServlet 'dispatcherServlet'
2018-07-20 14:59:36.547 INFO 17284 --- [ XNIO-1 task-1] o.s.w.s.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
2018-07-20 14:59:36.563 INFO 17284 --- [ XNIO-1 task-1] o.s.w.s.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 15ms
(3) 查看運行效果
經過上圖,咱們發現zipkin使用springboot,而且啓動的端口爲9411,而後咱們經過瀏覽器訪問,效果以下:
詳細參考:https://zipkin.io/pages/quick...
一、註冊中心 Eureka Server(可選的,只用於服務生產者和調用者註冊)
二、Zipkin服務器
三、服務的生產者及服務的調用者:
1)服務的生產者、調用者是相對的,二者之間能夠互相調用,便可以同時做爲生產者和調用者,二者都是Eureka Client;
2)二者都要註冊到註冊中心上,這樣才能夠相互可見,才能經過服務名來調用指定服務,才能使用Feign或RestTemplate+Ribbon來達到負載均衡
3)二者都要註冊到Zipkin服務器上,這樣Zipkin才能追蹤服務的調用鏈路
基本知識講解完畢,下面咱們來實戰,本文的案例主要有三個工程組成:一個server-zipkin,它的主要做用使用ZipkinServer 的功能,收集調用數據,並展現;一個service-hi,對外暴露hi接口;一個service-miya,對外暴露miya接口;這兩個service能夠相互調用;而且只有調用了,server-zipkin纔會收集數據的,這就是爲何叫服務追蹤了。
代碼地址(碼雲):https://gitee.com/wudiyong/ZipkinServer.git
一、新建一個普通的Spring Boot項目,工程取名爲server-zipkin,在其pom引入依賴:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dxz.serverzipkin</groupId> <artifactId>serverzipkin</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>server-zipkin</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> <!--配合spring cloud版本 --> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <!--設置字符編碼及java版本 --> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--增長zipkin的依賴 --> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-server</artifactId> </dependency> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-ui</artifactId> </dependency> <!--用於測試的,本例可省略 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <!--依賴管理,用於管理spring-cloud的依賴 --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-parent</artifactId> <version>Brixton.SR3</version> <!--官網爲Angel.SR4版本,可是我使用的時候老是報錯 --> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <!--使用該插件打包 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2在其程序入口類, 加上註解@EnableZipkinServer,開啓ZipkinServer的功能:
package com.dxz.serverzipkin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import zipkin.server.EnableZipkinServer; @EnableZipkinServer @SpringBootApplication public class ServerZipkinApplication { public static void main(String[] args) { SpringApplication.run(ServerZipkinApplication.class, args); } }
3在配置文件application.yml指定,配置Zipkin服務端口、名稱等:
server.port=9411 spring.application.name=my-zipkin-server
啓動後打開http://localhost:9411/能夠看到
以下圖,什麼內容都沒有,由於尚未任何服務註冊到Zipkin,一旦有服務註冊到Zipkin便在Service Name下拉列表中能夠看到服務名字,當有服務被調用,則能夠在Span Name中看到被調用的接口名字.
這裏爲了測試方便,咱們能夠將數據保存到內存中,可是生產環境仍是須要將數據持久化的,原生支持了不少產品,例如ES、數據庫等。
這二者配置是同樣的此處簡化,直接修改compute-server和feign-consumer兩個服務,修改有兩點:
一、pom增長
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
二、在其配置文件application.yml指定zipkin server的地址,頭經過配置「spring.zipkin.base-url」指定:
spring.zipkin.base-url=http://localhost:9411
至此,能夠開始測試Zipkin追蹤服務了
啓動順序:註冊中心(可選)->配置中心(可選)->Zipkin服務器->服務生產者及調用者
咱們能夠嘗試調用生產者或調用者的接口,而後刷新Zipkin服務器頁面,能夠看到以下結果:
依次啓動上面的三個工程,打開瀏覽器訪問:http://localhost:9411/,會出現如下界面:
再打開http://localhost:9411/的界面,點擊Dependencies,能夠發現服務的依賴關係:
點擊find traces,能夠看到具體服務相互調用的數據:
能夠看到,調用消費者(ribbon-consumer)耗時83ms,其中消費者調用生產者佔了5ms,佔比6%。
在測試的過程當中咱們會發現,有時候,程序剛剛啓動後,刷新幾回,並不能看到任何數據,緣由就是咱們的spring-cloud-sleuth收集信息是有必定的比率的,默認的採樣率是0.1,配置此值的方式在配置文件中增長spring.sleuth.sampler.percentage參數配置(若是不配置默認0.1),若是咱們調大此值爲1,能夠看到信息收集就更及時。可是當這樣調整後,咱們會發現咱們的rest接口調用速度比0.1的狀況下慢了不少,即便在0.1的採樣率下,咱們屢次刷新consumer的接口,會發現對同一個請求兩次耗時信息相差很是大,若是取消spring-cloud-sleuth後咱們再測試,會發現並無這種狀況,能夠看到這種方式追蹤服務調用鏈路會給咱們業務程序性能帶來必定的影響。
#sleuth採樣率,默認爲0.1,值越大收集越及時,但性能影響也越大
spring.sleuth.sampler.percentage=1
其實,咱們仔細想一想也能夠總結出這種方式的幾種缺陷:
缺陷1:zipkin客戶端向zipkin-server程序發送數據使用的是http的方式通訊,每次發送的時候涉及到鏈接和發送過程。
缺陷2:當咱們的zipkin-server程序關閉或者重啓過程當中,由於客戶端收集信息的發送採用http的方式會被丟失。
針對以上兩個明顯的缺陷,改進的辦法是:
一、通訊採用socket或者其餘效率更高的通訊方式。
二、客戶端數據的發送儘可能減小業務線程的時間消耗,採用異步等方式發送收集信息。
三、客戶端與zipkin-server之間增長緩存類的中間件,例如redis、MQ等,在zipkin-server程序掛掉或重啓過程當中,客戶端依舊能夠正常的發送本身收集的信息。
相信採用以上三種方式會很大的提升咱們的效率和可靠性。其實spring-cloud已經爲咱們提供採用MQ或redis等其餘的採用socket方式通訊,利用消息中間件或數據庫緩存的實現方式。
spring-cloud-sleuth-zipkin-stream方式的實現請看下面內容!
springcloud官方按照傳輸方式分紅了三種啓動服務端的方式:
只須要添加相應的依賴,以後配置相應的註解,如@EnableZipkinStreamServer
便可。具體配置參考官方文檔:
(http://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/1.2.1.RELEASE/#_adding_to_the_project)
一、加入依賴
要將http方式改成經過MQ通訊,咱們要將依賴的原來依賴的io.zipkin.java:zipkin-server換成spring-cloud-sleuth-zipkin-stream和spring-cloud-starter-stream-rabbit
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency>
二、在啓動類中開啓Stream通訊功能
package com.zipkinServer.ZipkinServer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.sleuth.zipkin.stream.EnableZipkinStreamServer; import zipkin.server.EnableZipkinServer; /* * @EnableZipkinServer、@EnableZipkinStreamServer二者二選一 * 經過源碼可看到,@EnableZipkinStreamServer包含了@EnableZipkinServer,同時 * 還建立了一個rabbit-mq的消息隊列監聽器,因此也支持原來的HTTP通訊方式 */ //@EnableZipkinServer//默認採用HTTP通訊方式啓動ZipkinServer @EnableZipkinStreamServer//採用Stream通訊方式啓動ZipkinServer,也支持HTTP通訊方式 @SpringBootApplication public class ZipkinServerApplication { public static void main(String[] args) { SpringApplication.run(ZipkinServerApplication.class, args); } }
三、配置消息中間件rabbit mq地址等信息
#鏈接rabbitmq服務器配置 spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest
至此,ZipkinServer配置完成,下面是Zipkin客戶端的配置
一、將原來的spring-cloud-starter-zipkin替換爲以下依賴便可
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
二、此外,在配置文件中也加上鍊接MQ的配置
#鏈接rabbitmq服務器配置
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
至此所有配置完成,能夠開始測試。
另外,因爲要鏈接到rabbitmq服務器,因此,還要安裝及啓動rabbitmq服務器!
加了MQ以後,通訊過程以下圖所示:
能夠看到以下效果:
1)請求的耗時時間不會出現忽然耗時特長的狀況
2)當ZipkinServer不可用時(好比關閉、網絡不通等),追蹤信息不會丟失,由於這些信息會保存在Rabbitmq服務器上,直到Zipkin服務器可用時,再從Rabbitmq中取出這段時間的信息
Zipkin目前只支持mysql數據庫,ZipkinServer服務作以下修改,其它服務不需作任何修改
一、加入數據庫依賴
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
二、在application.properties中配置數據庫屬性
#zipkin數據保存到數據庫中須要進行以下配置 #表示當前程序不使用sleuth spring.sleuth.enabled=false #表示zipkin數據存儲方式是mysql zipkin.storage.type=mysql #數據庫腳本建立地址,當有多個時可以使用[x]表示集合第幾個元素,腳本可到官網下載,須要先手動到數據庫執行 spring.datasource.schema[0]=classpath:/zipkin.sql #spring boot數據源配置 spring.datasource.url=jdbc:mysql://localhost:3306/zipkin?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.initialize=true spring.datasource.continue-on-error=true
三、zipkin.sql
數據庫腳本文件放到resources目錄下,且須要先手動到數據庫執行一次,內容以下:
CREATE TABLE IF NOT EXISTS zipkin_spans ( `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit', `trace_id` BIGINT NOT NULL, `id` BIGINT NOT NULL, `name` VARCHAR(255) NOT NULL, `parent_id` BIGINT, `debug` BIT(1), `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL', `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query' ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_spans ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `id`) COMMENT 'ignore insert on duplicate'; ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`, `id`) COMMENT 'for joining with zipkin_annotations'; ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds'; ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames'; ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range'; CREATE TABLE IF NOT EXISTS zipkin_annotations ( `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit', `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id', `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id', `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1', `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB', `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation', `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp', `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null', `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address', `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null', `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null' ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds'; ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames'; ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces'; ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces'; ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job'; CREATE TABLE IF NOT EXISTS zipkin_dependencies ( `day` DATE NOT NULL, `parent` VARCHAR(255) NOT NULL, `child` VARCHAR(255) NOT NULL, `call_count` BIGINT ) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci; ALTER TABLE zipkin_dependencies ADD UNIQUE KEY(`day`, `parent`, `child`);
至此,ZipkinServer採用數據庫存儲配置完成。
測試時發現,要用MQ異步方式通訊的pom.xml配置及@EnableZipkinStreamServer註解才能夠(@EnableZipkinServer貌似只能保存到內存),不然啓動報錯,不明白爲何。
前面講了利用mq的方式發送數據,存儲在mysql,實際生產過程當中調用數據量很是的大,mysql存儲並非很好的選擇,這時咱們能夠採用elasticsearch進行存儲
配置過程也很簡單
一、mysql依賴改爲elasticsearch依賴
<!-- 添加 spring-data-elasticsearch的依賴 --> <dependency> <groupId>io.zipkin.java</groupId> <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId> <version>1.24.0</version> <optional>true</optional> </dependency>
二、數據庫配置改爲elasticsearch配置
#表示當前程序不使用sleuth
spring.sleuth.enabled=false
#表示zipkin數據存儲方式是elasticsearch
zipkin.storage.StorageComponent = elasticsearch
zipkin.storage.type=elasticsearch
zipkin.storage.elasticsearch.cluster=elasticsearch-zipkin-cluster
zipkin.storage.elasticsearch.hosts=127.0.0.1:9300
# zipkin.storage.elasticsearch.pipeline=
zipkin.storage.elasticsearch.max-requests=64
zipkin.storage.elasticsearch.index=zipkin
zipkin.storage.elasticsearch.index-shards=5
zipkin.storage.elasticsearch.index-replicas=1
三、安裝elasticsearch
其它代碼徹底不變
具體見:
http://www.cnblogs.com/shunyang/p/7011306.html
http://www.cnblogs.com/shunyang/p/7298005.html
https://segmentfault.com/a/1190000012342007
https://blog.csdn.net/meiliangdeng1990/article/details/54131384