spring-cloud-sleuth+zipkin追蹤服務實現(一)
最近在學習spring cloud構建微服務,很多大牛都提供很多入門的例子幫助我們學習,對於我們這種英語不好的碼農來說,效率著實提高不少。這兩天學習到追蹤微服務rest服務調用鏈路的問題,接觸到zipkin,而spring cloud也提供了spring-cloud-sleuth來方便集成zipkin實現。
在網絡上找了好多文章,不過發現版本引入的maven依賴包,配置的參數都不完全相同。可能是因為版本更新太快 的原因,部分配置已經取消掉了。光看不動手始終是不夠的,於是自己根據其他大神的博客以及github上作者的示例來自己練手試試。
我們準備了三個必要的程序來做測試,分別是
1、zipkin-server
負責數據收集以及信息展示功能。
2、provider
負責微服務的生產者,對外提供 “https://127.0.0.1:10001/add/被加數/加數” 的rest地址來完成一個簡單的兩整數相加的功能。
3、consumer
負責微服務的調用,對外提供 "https://127.0.0.1:10002/test/add/被加數/加數" 的rest地址,當訪問此地址時,使用feign方式調用provider的rest服務地址。得到計算結果後,顯示在界麵上。
三個程序功能非常簡單,接下來我們看看每個程序的具體代碼和配置。為了方便我們對三個模塊開發,我們在父POM文件中添加了spring-boot和spring-cloud的依賴,避免子模塊中需要寫版本號
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
接下來我們看看三個程序中的相關配置
一、zipkin-server
首先,我們添加maven依賴配置
<dependencies>
<!--使用@EnableZipkinServer注解方式隻需要依賴如下兩個包-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<scope>runtime</scope>
</dependency>
<!--保存到數據庫需要如下依賴-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-storage-mysql</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
線下測試環境中,我們可以將數據保存到內存中,但是生產環境還是需要將數據持久化中。原生支持了很多產品,例如ES、數據庫等,本例中我們采用持久化到mysql中的方式來演示。
我們寫一個啟動類ZipkinServer,代碼非常簡單,如下
@SpringBootApplication
@EnableZipkinServer //啟動ZipkinServer段
public class ZipkinServer {
public static void main(String[] args) {
SpringApplication.run(ZipkinServer.class, args);
}
}
接下來我們配置application.properties配置文件
server.port=9411
spring.application.name=zipkin-server
#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的數據庫,初始化腳本為classpath下的zipkin.sql的sql文件。具體內容見附件。
啟動後 無異常輸出,這樣我們的zipkin-server程序就OK了
二、provider和consumer
provider和consumer兩個程序,與其他基礎代碼我們就不多講了(相信學些到這一步的童鞋,都已經對spring cloud創建微服務以上手了),兩個程序在spring-cloud-sleuth相關的配置都是一樣。
首先,我們要在二者的POM文件中添加依賴,引入zipkin客戶端自動配置相關依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
其次,在配置文件application中,我們加入zipkin-server收集信息的地址
#配置zipKin Server的地址
spring.zipkin.base-url=https://127.0.0.1:9411
這樣我們的兩個微服務就配置好了(注意這裏我們並不會再說明如何寫rest接口和使用feign調用rest接口)
三、測試
啟動我們的三個程序。然後訪問zipkin-server程序的UI界麵地址https://127.0.0.1:9411,可以看到如下的效果
其中Span Name選項為灰色不可選,說明目前沒有數據,我們查看數據庫也可以看到沒有任何數據信息。接下來我們訪問consumer提供的訪問地址 “https://127.0.0.1:10001/add/被加數/加數” 刷新幾次之後,我們再次刷新我們的zipkin界麵,可以看到Span Name已經可以選擇了。
點擊Find Traces按鈕,我們可以看到調用的鏈路和耗時情況,點擊Dependencies,我們可以看到provider和consumer的調用圖
OK,我們的簡單實用spring-cloud-sleuth+zipkin的例子就完成了。
四、拓展
在測試的過程中我們會發現,有時候,程序剛剛啟動後,刷新幾次,並不能看到任何數據,原因就是我們的spring-cloud-sleuth收集信息是有一定的比率的,默認的采樣率是0.1,配置此值的方式在配置文件中增加spring.sleuth.sampler.percentage參數配置(如果不配置默認0.1),如果我們調大此值為1,可以看到信息收集就更及時。但是當這樣調整後,我們會發現我們的rest接口調用速度比0.1的情況下慢了很多,即時在0.1的采樣率下,我們多次刷新consumer的接口,也會出現如下情況
紅色框中上下兩個數據是兩次耗時信息,可以看到相差非常大,如果取消spring-cloud-sleuth後我們再測試,會發現並沒有這種情況,可以看到這種方式追蹤服務調用鏈路會給我們業務程序性能帶來一定的影響。
其實,我們自己仔細想也可以簡單總結出這種方式的幾種缺陷
缺陷1:zipkin客戶端向zipkin-server程序發送數據使用的是http的方式通信,每次發送的時候涉及到連接和發送過程。
缺陷2:當我們的zipkin-server程序關閉或者重啟過程中,因為客戶端收集信息的發送采用http的方式會被丟失。
針對以上兩個明顯的缺陷,改進的辦法是
1、通信采用socket或者其他效率更高的通信方式。
2、客戶端數據的發送盡量減少業務線程的時間消耗,采用異步等方式發送收集信息。
3、客戶端與zipkin-server之間增加緩存類的中間件,例如redis、MQ等,在zipkin-server程序掛掉或重啟過程中,客戶端依舊可以正常的發送自己收集的信息。
相信采用以上三種方式會很大的提高我們的效率和可靠性。其實spring-cloud以及為我們提供采用MQ或redis等其他的采用socket方式通信,利用消息中間件或數據庫緩存的實現方式。下一次我們再來測試spring-cloud-sleuth-zipkin-stream方式的實現。
參考文檔:
https://github.com/spring-cloud/spring-cloud-sleuth
菜鳥學文,望大俠指正。
最後更新:2017-05-05 14:33:44