javascript
Spring Cloud构建微服务架构:分布式服务跟踪(入门)【Dalston版】
通過之前的N篇博文介紹,實際上我們已經(jīng)能夠通過使用它們搭建起一個基礎(chǔ)的微服務(wù)架構(gòu)系統(tǒng)來實現(xiàn)我們的業(yè)務(wù)需求了。但是,隨著業(yè)務(wù)的發(fā)展,我們的系統(tǒng)規(guī)模也會變得越來越大,各微服務(wù)間的調(diào)用關(guān)系也變得越來越錯綜復(fù)雜。通常一個由客戶端發(fā)起的請求在后端系統(tǒng)中會經(jīng)過多個不同的微服務(wù)調(diào)用來協(xié)同產(chǎn)生最后的請求結(jié)果,在復(fù)雜的微服務(wù)架構(gòu)系統(tǒng)中,幾乎每一個前端請求都會形成一條復(fù)雜的分布式服務(wù)調(diào)用鏈路,在每條鏈路中任何一個依賴服務(wù)出現(xiàn)延遲過高或錯誤的時候都有可能引起請求最后的失敗。這時候?qū)τ诿總€請求全鏈路調(diào)用的跟蹤就變得越來越重要,通過實現(xiàn)對請求調(diào)用的跟蹤可以幫助我們快速的發(fā)現(xiàn)錯誤根源以及監(jiān)控分析每條請求鏈路上的性能瓶頸等好處。
針對上面所述的分布式服務(wù)跟蹤問題,Spring Cloud Sleuth提供了一套完整的解決方案。在本章中,我們將詳細(xì)介紹如何使用Spring Cloud Sleuth來為我們的微服務(wù)架構(gòu)增加分布式服務(wù)跟蹤的能力。
快速入門
在介紹各種概念與原理之前,我們先通過實現(xiàn)一個簡單的示例,對存在服務(wù)調(diào)用的應(yīng)用增加一些sleuth的配置實現(xiàn)基本的服務(wù)跟蹤功能,以此來對Spring Cloud Sleuth有一個初步的了解,隨后再逐步展開介紹實現(xiàn)過程中的各個細(xì)節(jié)部分。
準(zhǔn)備工作
在引入Sleuth之前,我們先按照之前章節(jié)學(xué)習(xí)的內(nèi)容來做一些準(zhǔn)備工作,構(gòu)建一些基礎(chǔ)的設(shè)施和應(yīng)用:
服務(wù)注冊中心:eureka-server,這里不做贅述,直接使用之前構(gòu)建的工程。或者直接使用我的公益eureka注冊中心,下面的例子使用該注冊中心。
微服務(wù)應(yīng)用:trace-1,實現(xiàn)一個REST接口/trace-1,調(diào)用該接口后將觸發(fā)對trace-2應(yīng)用的調(diào)用。具體實現(xiàn)如下:
- 創(chuàng)建一個基礎(chǔ)的Spring Boot應(yīng)用,在pom.xml中增加下面依賴:
| <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.10.RELEASE</version> <relativePath/> </parent> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Dalston.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> |
- 創(chuàng)建應(yīng)用主類,并實現(xiàn)/trace-1接口,并使用RestTemplate調(diào)用trace-2應(yīng)用的接口。具體如下:
public class TraceApplication { private final Logger logger = Logger.getLogger(getClass()); RestTemplate restTemplate() { return new RestTemplate(); } (value = "/trace-1", method = RequestMethod.GET) public String trace() { logger.info("===call trace-1==="); return restTemplate().getForEntity("http://trace-2/trace-2", String.class).getBody(); } public static void main(String[] args) { SpringApplication.run(TraceApplication.class, args); } } |
- application.properties中將eureka.client.serviceUrl.defaultZone參數(shù)指向eureka-server的地址,具體如下:
| spring.application.name=trace-1 server.port=9101 eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/ |
微服務(wù)應(yīng)用:trace-2,實現(xiàn)一個REST接口/trace-2,供trace-1調(diào)用。具體實現(xiàn)如下:
創(chuàng)建一個基礎(chǔ)的Spring Boot應(yīng)用,pom.xml中的依賴與trace-1相同
創(chuàng)建應(yīng)用主類,并實現(xiàn)/trace-2接口,具體實現(xiàn)如下:
public class TraceApplication { private final Logger logger = Logger.getLogger(getClass()); (value = "/trace-2", method = RequestMethod.GET) public String trace() { logger.info("===<call trace-2>==="); return "Trace"; } public static void main(String[] args) { SpringApplication.run(TraceApplication.class, args); } } |
- application.properties中將eureka.client.serviceUrl.defaultZone參數(shù)指向eureka-server的地址,另外還需要設(shè)置不同的應(yīng)用名和端口號,具體如下:
| spring.application.name=trace-2 server.port=9102 eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/ |
在實現(xiàn)了上面內(nèi)容之后,我們可以將eureka-server、trace-1、trace-2三個應(yīng)用都啟動起來,并通過postman或curl等工具來對trace-1的接口發(fā)送請求http://localhost:9101/trace-1,我們可以得到返回值Trace,同時還能在它們的控制臺中分別獲得下面的輸出:
| -- trace-1 INFO 25272 --- [nio-9101-exec-2] ication$$EnhancerBySpringCGLIB$$36e12c68 : ===<call trace-1>=== -- trace-2 INFO 7136 --- [nio-9102-exec-1] ication$$EnhancerBySpringCGLIB$$52a02f0b : ===<call trace-2>=== |
實現(xiàn)跟蹤
在完成了準(zhǔn)備工作之后,接下來我們開始進行本章的主題內(nèi)容,為上面的trace-1和trace-2來添加服務(wù)跟蹤功能。通過Spring Cloud Sleuth的封裝,我們?yōu)閼?yīng)用增加服務(wù)跟蹤能力的操作非常簡單,只需要在trace-1和trace-2的pom.xml依賴管理中增加spring-cloud-starter-sleuth依賴即可,具體如下:
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> |
到這里,實際上我們已經(jīng)為trace-1和trace-2實現(xiàn)服務(wù)跟蹤做好了基礎(chǔ)的準(zhǔn)備,重啟trace-1和trace-2后,再對trace-1的接口發(fā)送請求http://localhost:9101/trace-1。此時,我們可以從它們的控制臺輸出中,窺探到sleuth的一些端倪。
| -- trace-1 INFO [trace-1,f410ab57afd5c145,a9f2118fa2019684,false] 25028 --- [nio-9101-exec-1] ication$$EnhancerBySpringCGLIB$$d8228493 : ===<call trace-1>=== -- trace-2 INFO [trace-2,f410ab57afd5c145,e9a377dc2268bc29,false] 23112 --- [nio-9102-exec-1] ication$$EnhancerBySpringCGLIB$$e6cb4078 : ===<call trace-2>=== |
從上面的控制臺輸出內(nèi)容中,我們可以看到多了一些形如[trace-1,f410ab57afd5c145,a9f2118fa2019684,false]的日志信息,而這些元素正是實現(xiàn)分布式服務(wù)跟蹤的重要組成部分,它們每個值的含義如下:
- 第一個值:trace-1,它記錄了應(yīng)用的名稱,也就是application.properties中spring.application.name參數(shù)配置的屬性。
- 第二個值:f410ab57afd5c145,Spring Cloud Sleuth生成的一個ID,稱為Trace ID,它用來標(biāo)識一條請求鏈路。一條請求鏈路中包含一個Trace ID,多個Span ID。
- 第三個值:a9f2118fa2019684,Spring Cloud Sleuth生成的另外一個ID,稱為Span ID,它表示一個基本的工作單元,比如:發(fā)送一個HTTP請求。
- 第四個值:false,表示是否要將該信息輸出到Zipkin等服務(wù)中來收集和展示。
上面四個值中的Trace ID和Span ID是Spring Cloud Sleuth實現(xiàn)分布式服務(wù)跟蹤的核心。在一次服務(wù)請求鏈路的調(diào)用過程中,會保持并傳遞同一個Trace ID,從而將整個分布于不同微服務(wù)進程中的請求跟蹤信息串聯(lián)起來,以上面輸出內(nèi)容為例,trace-1和trace-2同屬于一個前端服務(wù)請求來源,所以他們的Trace ID是相同的,處于同一條請求鏈路中。
本文完整示例:
讀者可以根據(jù)喜好選擇下面的兩個倉庫中查看trace-1和trace-2兩個項目:
- Github
- Gitee
如果您對這些感興趣,歡迎star、follow、收藏、轉(zhuǎn)發(fā)給予支持!
本文內(nèi)容部分節(jié)選自我的《Spring Cloud微服務(wù)實戰(zhàn)》,但對依賴的Spring Boot和Spring Cloud版本做了升級。
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud构建微服务架构:分布式服务跟踪(入门)【Dalston版】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Quartz应用与集群原理分析
- 下一篇: ReactiveCocoa中潜在的内存泄