springcloud-sleuth+zipkin入門一
說明
zipkin是twitter公司基於Google的drapper論文,建立一套分散式、服務計時框架,可以用於鏈路跟蹤。目前有的java版本的實現有DropWizard zipkin和Springcloud-sleuth+zipkin等。本文是搭建Springcloud的入門例項。
重要概念
trace:個人理解,是一條鏈路的抽象,表示了一次完成的鏈路資訊。traceid是該鏈路的唯一標識
span:是鏈路呼叫的節點,是鏈路上一次方法執行的過程。spanId是該過程的標識,同時span可以通過新增tag的方式附加業務資訊。
Springcloud針對鏈路節點過程抽象了四種類型:
sr:server receive服務端接收
ss:server send 服務端傳送
cr: client receive 客戶端接收
cs:Client send 客戶端傳送。
下圖說明了Springsleuth的鏈路呼叫圖:
引入上下級span關係後可以形成下面鏈路圖:
搭建Springcloud-sleuth+zipkin
1環境說明
- 開發IDE:intellij IDEA2017
- jdk:1.8
- maven:3.3.9
- springboot:1.5.2RELEASE
- springcloud:Camden.SR7
2建立zipkin伺服器
建立maven工程,並在pom.xml中引入zipkin相關依賴如下:
<!--引入Springzipkinserver-->
<dependency>
<groupId >io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.4.2</version>
</dependency>
<!--引入Springzipkinwebui-->
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId >zipkin-autoconfigure-ui</artifactId>
<version>2.4.2</version>
</dependency>
zipkinui是用於頁面顯示用的。
建立Springboot啟動類,並添加註解@EnableZipkinServer,表示為zipkin伺服器。
@SpringBootApplication
@EnableZipkinServer
public class ZipkinServerApplicatoin {
public static void main(String[] args) {
SpringApplication.run(ZipkinServerApplicatoin.class,args);
}
}
3建立zipkin監控服務
建立maven專案並在pom.xml檔案中加入如下程式碼:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR7</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入zipkin-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
注意Springcloud依賴管理的版本,不同的版本可能會報錯。這裡我們使用的是Camden.SR7版本。
在resources/application.yml中加入如下配置:
server:
port: 8082
spring:
application:
name: zipkinclientserverone
zipkin:
base-url: http://localhost:8080
sleuth:
sampler:
percentage: 1.0
這裡我們將抽樣率percentage:設定為100%,表示會抽取所有記錄。
建立rest客戶端:
@RestController
public class SleuthController {
@ResponseBody
@RequestMapping("/sayHello/{name}")
public String sayHello(@PathVariable String name) {
return "hello " + name;
}
}
到這裡最簡單的單個服務的鏈路耗時呼叫就 完成了。
說明
- 這種整合的zipkin資訊是預設儲存在記憶體中的
- 客戶端的sleuth資訊,是通過socket請求傳送到zipkin伺服器的,客戶端會不停掃描sleuth佇列,一旦有資訊就推送到zipkin伺服器
- 客戶端多級服務鏈路採集是通過新增請求頭實現的,原理是通過AOP切面,在請求頭裡新增鏈路資訊,二級服務,通過filter獲取鏈路資訊併發送到zipkin伺服器。
- Spring支援的二級服務呼叫方式有:feign、resttemplate兩種方式,當然,這兩種方式都要求通過Spring容器來做。如果自己建立連線或者resttemplate是不可能被Spring處理的,畢竟是AOP方式實現鏈路資訊新增。
- zipkin服務端是通過HttpProcesser來處理鏈路資訊,因此想要通過webfilter實現攔截是不可能的。
4多級服務呼叫鏈路
上面完成了單級服務呼叫,這裡我們在建立一個zipkin監視服務,並且該服務為上面服務提供服務支援。建立過程如上面一致,只是將埠改為8888。這裡不再贅述
5修改第一個工程加入RestTemplate支援和Feign支援
增加RestTemplate配置,由Spring管理restTemplate,否則不能被鏈路呼叫攔截。
@Configuration
public class RestTemplateConfiguration {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
建立feign呼叫api
@FeignClient(name = "sleuthService",url = "http://localhost:8888")
public interface SleuthService {
@RequestMapping("/sayHello/{name}")
public String sayHello(@PathVariable(name="name")String name);
}
修改controller
@RestController
public class SleuthController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private SleuthService sleuthService;
@ResponseBody
@RequestMapping("/sayHello/{name}")
public String sayHello(@PathVariable String name) {
return "hello " + name;
}
@ResponseBody
@RequestMapping("/restHello/{name}")
public String restHello(@PathVariable String name){
return restTemplate.getForObject("http://localhost:8888/sayHello/" + name,String.class );
}
@ResponseBody
@RequestMapping("/feignHello/{name}")
public String feignHello(@PathVariable String name){
return sleuthService.sayHello(name);
}
}