在分佈式架構中,需要對分佈式服務進行治理,也就是要記錄到服務的調用和被調用的具體信息,比如調用時間,響應時間等等。稱爲服務的調用鏈。記錄每個服務的調用鏈–分佈式服務服務跟蹤。
Spring Cloud Sleuth爲Spring Cloud實現分佈式跟蹤解決方案。
Span:工作的基本單位 例如,發送RPC是一個新的跨度,以及向RPC發送響應。Span由跨度的唯一64位ID標識,跨度是其中一部分的跟蹤的另一個64位ID。跨度還具有其他數據,例如描述,時間戳記事件,鍵值註釋(標籤),導致它們的跨度的ID以及進程ID(通常是IP地址)。
跨距開始和停止,他們跟蹤他們的時間信息。創建跨度後,必須在將來的某個時刻停止。
啓動跟蹤的初始範圍稱爲root span。該跨度的跨度id的值等於跟蹤ID。
跟蹤:一組spans形成樹狀結構。例如,如果您正在運行分佈式大數據存儲,則可能會由put請求形成跟蹤。
註釋: 用於及時記錄事件的存在。用於定義請求的開始和停止的一些核心註釋是:
cs - 客戶端發送 - 客戶端已經發出請求。此註釋描繪了跨度的開始。
sr - 服務器接收 - 服務器端得到請求,並將開始處理它。如果從此時間戳中減去cs時間戳,則會收到網絡延遲。
ss - 服務器發送 - 在完成請求處理後(響應發送回客戶端時)註釋。如果從此時間戳中減去sr時間戳,則會收到服務器端處理請求所需的時間。
cr - 客戶端接收 - 表示跨度的結束。客戶端已成功接收到服務器端的響應。如果從此時間戳中減去cs時間戳,則會收到客戶端從服務器接收響應所需的整個時間。
可視化Span和Trace將與Zipkin註釋一起查看系統:
構建項目server-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.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
完整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.heyuanjun.server-zipkin</groupId>
<artifactId>server-zipkin</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.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<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-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>repository.springframework.maven.snapshot</id>
<name>Spring Framework Maven Snapshot Repository</name>
<url>http://repo.spring.io/snapshot/</url>
</repository>
</repositories>
</project>
啓動類上加上註解@EnableZipkinServer,
/**
* @author heyuanjun
*/
@SpringBootApplication
@EnableZipkinServer
public class ServerZipkinApplication {
public static void main(String[] args) {
SpringApplication.run(ServerZipkinApplication.class, args);
}
}
配置文件作配置
server.port=9411
構建ZipkinClient項目,添加依賴
org.springframework.cloud
spring-cloud-starter-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.heyuanjun.zipkin-client</groupId>
<artifactId>zipkin-client</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zipkin-client</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>repository.springframework.maven.snapshot</id>
<name>Spring Framework Maven Snapshot Repository</name>
<url>http://repo.spring.io/snapshot/</url>
</repository>
</repositories>
</project>
配置文件作如下配置
server.port=8999
spring.zipkin.base-url=http://localhost:9411
spring.application.name=service-sayhi
接口暴露
package com.heyuanjun.zipkinclient.zipkinclient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author DELL
*/
@SpringBootApplication
@RestController
public class ZipkinClientApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinClientApplication.class, args);
}
private static final Logger LOG = Logger.getLogger(ZipkinClientApplication.class.getName());
@Autowired
private RestTemplate restTemplate;
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@RequestMapping("/sayHello")
public String callHome(){
LOG.log(Level.INFO, "調用zipClient2的sayHello");
return restTemplate.getForObject("http://127.0.0.1:8989/hi", String.class);
}
@RequestMapping("/hi")
public String info(){
LOG.log(Level.INFO, "調用zipClient");
return "這裏是 zipClint1 的info接口";
}
@Bean
public AlwaysSampler defaultSampler(){
return new AlwaysSampler();
}
}
構建zipclient2,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.heyuanjun.zipclient2</groupId>
<artifactId>zipclient2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zipclient2</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Camden.SR7</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<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>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>repository.springframework.maven.snapshot</id>
<name>Spring Framework Maven Snapshot Repository</name>
<url>http://repo.spring.io/snapshot/</url>
</repository>
</repositories>
</project>
server.port=8989
spring.zipkin.base-url=http://localhost:9411
spring.application.name=service-sayhello
接口暴露
package com.heyuanjun.zipclient2.zipclient2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.sleuth.sampler.AlwaysSampler;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author DELL
*/
@SpringBootApplication
@RestController
public class Zipclient2Application {
public static void main(String[] args) {
SpringApplication.run(Zipclient2Application.class, args);
}
private static final Logger LOG = Logger.getLogger(Zipclient2Application.class.getName());
@RequestMapping("/hi")
public String home(){
LOG.log(Level.INFO, "hi is being called");
return "這裏是Cilent2的hi接口";
}
@RequestMapping("/sayHello")
public String info(){
LOG.log(Level.INFO, "調用zipClient的info");
return restTemplate.getForObject("http://127.0.0.1:8999/hi",String.class);
}
@Autowired
private RestTemplate restTemplate;
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
@Bean
public AlwaysSampler defaultSampler(){
return new AlwaysSampler();
}
}
瀏覽器訪問http://localhost:9411/
瀏覽器訪問http://localhost:8989/sayHello
http://localhost:9411/dependency
可以看到服務之間相互調用的數據。
注意:接口名稱不能使用info,info應該已經被內部使用了,調用info返回空數據。
各種IT書籍書目及下載鏈接
https://blog.csdn.net/dh1027/article/details/89327978