微服務架構上通過業務來划分服務的,通過REST調用,對外暴露的一個接口,可能需要很多個服務協同才能完成這個接口功能,如果鏈路上任何一個服務出現問題或者網絡超時,都會形成導致接口調用失敗。隨着業務的不斷擴張,服務之間互相調用會越來越復雜,在項目中引入sleuth可以方便程序進行調試。
Spring Cloud Sleuth為服務之間調用提供鏈路追蹤。通過Sleuth可以很清楚的了解到一個服務請求經過了哪些服務,每個服務處理花費了多長。從而讓我們可以很方便的理清各微服務間的調用關系。此外Sleuth可以幫助我們:
- 耗時分析: 通過Sleuth可以很方便的了解到每個采樣請求的耗時,從而分析出哪些服務調用比較耗時;
- 可視化錯誤: 對於程序未捕捉的異常,可以通過集成Zipkin服務界面上看到;
- 鏈路優化: 對於調用比較頻繁的服務,可以針對這些服務實施一些優化措施。
改造前面的feign、service(服務)
pom增加:
<!--sleuth跟蹤--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency>
feign增加日志:
@Autowired
private IFeignService feignService; private static Logger log = LoggerFactory.getLogger(FeignController.class); @RequestMapping("/index") public String index(){ log.info("feign info"); return feignService.index(); // @FeignClient(value = "service-hello")
}
service增加日志:
private static Logger log = LoggerFactory.getLogger(HelloController.class);
@RequestMapping("/index")
public String index() {
log.info("service info");
System.err.println("服務提供者client:" + name + "服務端口:" + port);
return "服務提供者client:" + name + "服務端口:" + port;
}
啟動測試,打開eureka、feign、service

打開頁面,正常
顯示的日志如下:
2018-12-29 16:24:26.048 INFO [service-feign,1d270312e94cab85,1d270312e94cab85,false] 10692 --- [nio-8886-exec-8] c.e.fegin.controller.FeignController : feign info 2018-12-29 16:24:26.056 INFO [service-hello,1d270312e94cab85,5e23c30b75ee6755,false] 6560 --- [nio-8883-exec-5] c.e.e.controller.HelloController : service info
[appname,traceId,spanId,exportable]
,也就是Sleuth的跟蹤數據。其中:
- appname: 為微服務的服務名稱;
- traceId\spanId: 為Sleuth鏈路追蹤的兩個術語,后面我們再仔細介紹;
- exportable 是否是發送給Zipkin
整合Zipkin服務
Zipkin是一個致力於收集分布式服務的時間數據的分布式跟蹤系統。其主要涉及以下四個組件:
- collector: 數據采集;
- storage: 數據存儲;
- search: 數據查詢;
- UI: 數據展示.
Zipkin提供了可插拔數據存儲方式:In-Memory、MySql、Cassandra以及Elasticsearch。接下來的測試為方便直接采用In-Memory方式進行存儲,個人推薦Elasticsearch,特別是后續當我們需要整合ELK時。
構建zipkin項目
用的springboot2,所以構建zipkin沒有找到適合的方法(@EnableZipkinServer....失效),所以直接在官網https://zipkin.io/下載了jar包運行:
打開http://localhost:9411
修改feign、service:
<!--sleuth跟蹤--> <!--<dependency>--> <!--<groupId>org.springframework.cloud</groupId>--> <!--<artifactId>spring-cloud-starter-sleuth</artifactId>--> <!--</dependency>--> <!-- Zipkin 已包含spring-cloud-starter-sleuth --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
properties配置:
spring.zipkin.base-url=http://localhost:9411
spring.sleuth.sampler.percentage=1.0 # 默認
我們在瀏覽器中訪問幾次服務http://localhost:8886/index,然后轉到Zipkin服務器
該界面對本次請求進行了更詳細的展現。同樣我們還可以再點擊,以查看更為詳細的數據,可以看到如下界面
在Zipkin界面中我們還可以查看各服務之間的依賴關系
錯誤信息
Zipkin可以在跟蹤記錄中顯示錯誤信息。當異常拋出並且沒有捕獲,Zipkin就會自動的換個顏色顯示。在跟蹤記錄的清單中,當看到紅色的記錄時,就表示有異常拋出了。
關掉service-hello

點擊進去以獲取更詳細的錯誤信息。
采樣率
在生成環境中,由於業務量比較大,所產生的跟蹤數據可能會非常大,如果全部采集一是對業務有一定影響,二是對存儲壓力也會比較大,所以采樣變的很重要。一般來說,我們也不需要把每一個發生的動作都進行記錄。
Spring Cloud Sleuth有一個Sampler策略,可以通過這個實現類來控制采樣算法。采樣器不會阻礙span相關id的產生,但是會對導出以及附加事件標簽的相關操作造成影響。 Sleuth默認采樣算法的實現是Reservoir sampling,具體的實現類是PercentageBasedSampler
,默認的采樣比例為: 0.1
(即10%)。
我們可以通過spring.sleuth.sampler.percentage
來設置,所設置的值介於0.0到1.0之間,1.0則表示全部采集。
也可以通過實現bean的方式來設置采樣為全部采樣(AlwaysSampler)或者不采樣(NeverSampler)
鏈接:https://www.jianshu.com/p/c3d191663279
來源:簡書