SpringCloud教程九:Sleuth(服务链路追踪)
一、概述
Spring cloud sleuth
组件正是为了解决微服务跟踪的组件。二、原理
微服务架构上通过业务来划分服务的,通过REST调用,对外暴露的一个接口,可能需要很多个服务协同才能完成这个接口功能,如果链路上任何一个服务出现问题或者网络超时,都会形成导致接口调用失败。随着业务的不断扩张,服务之间互相调用会越来越复杂。
随着服务的越来越多,对调用链的分析会越来越复杂。它们之间的调用关系也许如下:
三、实践
本文的案例主要有三个工程组成:一个server-zipkin,它的主要作用使用ZipkinServer 的功能,收集调用数据,并展示;一个service-hi,对外暴露hi接口;一个service-miya,对外暴露miya接口;这两个service可以相互调用;并且只有调用了,server-zipkin才会收集数据的,这就是为什么叫服务追踪了。
3.1 创建server-zipkin
pom.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.wyma</groupId> 7 <artifactId>server-zipkin</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>server-zipkin</name> 12 <description>Demo project for Spring Boot</description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>1.5.2.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 </properties> 26 27 <dependencies> 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter</artifactId> 31 </dependency> 32 33 <dependency> 34 <groupId>org.springframework.boot</groupId> 35 <artifactId>spring-boot-starter-web</artifactId> 36 </dependency> 37 <dependency> 38 <groupId>org.springframework.boot</groupId> 39 <artifactId>spring-boot-starter-test</artifactId> 40 <scope>test</scope> 41 </dependency> 42 43 <dependency> 44 <groupId>io.zipkin.java</groupId> 45 <artifactId>zipkin-server</artifactId> 46 </dependency> 47 48 <dependency> 49 <groupId>io.zipkin.java</groupId> 50 <artifactId>zipkin-autoconfigure-ui</artifactId> 51 </dependency> 52 53 </dependencies> 54 55 <dependencyManagement> 56 <dependencies> 57 <dependency> 58 <groupId>org.springframework.cloud</groupId> 59 <artifactId>spring-cloud-dependencies</artifactId> 60 <version>Camden.SR6</version> 61 <type>pom</type> 62 <scope>import</scope> 63 </dependency> 64 </dependencies> 65 </dependencyManagement> 66 67 <build> 68 <plugins> 69 <plugin> 70 <groupId>org.springframework.boot</groupId> 71 <artifactId>spring-boot-maven-plugin</artifactId> 72 </plugin> 73 </plugins> 74 </build> 75 76 77 </project>
配置文件application.properties为:
1 server.port=9411
在其程序入口类, 加上注解@EnableZipkinServer,开启ZipkinServer的功能:
1 @SpringBootApplication 2 @EnableZipkinServer 3 public class ServerZipkinApplication { 4 5 public static void main(String[] args) { 6 SpringApplication.run(ServerZipkinApplication.class, args); 7 } 8 9 }
3.2 service-hello1
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.wyma</groupId> 7 <artifactId>service-zipkin</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>service-hello1</name> 12 <description>Demo project for Spring Boot</description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>1.5.2.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 </properties> 26 27 <dependencies> 28 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-web</artifactId> 32 </dependency> 33 <!--compile('org.springframework.cloud:spring-cloud-starter-zipkin')--> 34 35 <dependency> 36 <groupId>org.springframework.cloud</groupId> 37 <artifactId>spring-cloud-starter-zipkin</artifactId> 38 </dependency> 39 40 <dependency> 41 <groupId>org.springframework.boot</groupId> 42 <artifactId>spring-boot-starter-test</artifactId> 43 <scope>test</scope> 44 </dependency> 45 </dependencies> 46 47 <dependencyManagement> 48 <dependencies> 49 <dependency> 50 <groupId>org.springframework.cloud</groupId> 51 <artifactId>spring-cloud-dependencies</artifactId> 52 <version>Dalston.RC1</version> 53 <type>pom</type> 54 <scope>import</scope> 55 </dependency> 56 </dependencies> 57 </dependencyManagement> 58 59 <build> 60 <plugins> 61 <plugin> 62 <groupId>org.springframework.boot</groupId> 63 <artifactId>spring-boot-maven-plugin</artifactId> 64 </plugin> 65 </plugins> 66 </build> 67 68 <repositories> 69 <repository> 70 <id>spring-milestones</id> 71 <name>Spring Milestones</name> 72 <url>https://repo.spring.io/milestone</url> 73 <snapshots> 74 <enabled>false</enabled> 75 </snapshots> 76 </repository> 77 </repositories> 78 79 80 </project>
在其配置文件application.yml指定zipkin server的地址,头通过配置“spring.zipkin.base-url”指定:
1 server.port=8988 2 spring.zipkin.base-url=http://localhost:9411 3 spring.application.name=service-hello1
对外接口:
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.cloud.sleuth.sampler.AlwaysSampler; 5 import org.springframework.context.annotation.Bean; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 import org.springframework.web.bind.annotation.RestController; 8 import org.springframework.web.client.RestTemplate; 9 10 import java.util.logging.Level; 11 import java.util.logging.Logger; 12 13 @SpringBootApplication 14 @RestController 15 public class ServiceHelloApplication { 16 17 public static void main(String[] args) { 18 SpringApplication.run(ServiceHelloApplication.class, args); 19 } 20 private static final Logger LOG = Logger.getLogger(ServiceHelloApplication.class.getName()); 21 22 23 @Autowired 24 private RestTemplate restTemplate; 25 26 @Bean 27 public RestTemplate getRestTemplate(){ 28 return new RestTemplate(); 29 } 30 31 @RequestMapping("/hello") 32 public String callHome(){ 33 LOG.log(Level.INFO, "calling trace service-hello "); 34 return restTemplate.getForObject("http://localhost:8989/miya", String.class); 35 } 36 @RequestMapping("/info") 37 public String info(){ 38 LOG.log(Level.INFO, "calling trace service-hello "); 39 40 return "i'm service-hello"; 41 42 } 43 44 @Bean 45 public AlwaysSampler defaultSampler(){ 46 return new AlwaysSampler(); 47 } 48 }
3.3 service-miya
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.wyma</groupId> 7 <artifactId>service-miya</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>service-miya</name> 12 <description>Demo project for Spring Boot</description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>1.5.2.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 </properties> 26 27 <dependencies> 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-web</artifactId> 31 </dependency> 32 <!--compile('org.springframework.cloud:spring-cloud-starter-zipkin')--> 33 34 <dependency> 35 <groupId>org.springframework.cloud</groupId> 36 <artifactId>spring-cloud-starter-zipkin</artifactId> 37 </dependency> 38 39 <dependency> 40 <groupId>org.springframework.boot</groupId> 41 <artifactId>spring-boot-starter-test</artifactId> 42 <scope>test</scope> 43 </dependency> 44 45 46 </dependencies> 47 48 <dependencyManagement> 49 <dependencies> 50 <dependency> 51 <groupId>org.springframework.cloud</groupId> 52 <artifactId>spring-cloud-dependencies</artifactId> 53 <version>Dalston.RC1</version> 54 <type>pom</type> 55 <scope>import</scope> 56 </dependency> 57 </dependencies> 58 </dependencyManagement> 59 60 <build> 61 <plugins> 62 <plugin> 63 <groupId>org.springframework.boot</groupId> 64 <artifactId>spring-boot-maven-plugin</artifactId> 65 </plugin> 66 </plugins> 67 </build> 68 69 <repositories> 70 <repository> 71 <id>spring-milestones</id> 72 <name>Spring Milestones</name> 73 <url>https://repo.spring.io/milestone</url> 74 <snapshots> 75 <enabled>false</enabled> 76 </snapshots> 77 </repository> 78 </repositories> 79 80 81 </project>
配置文件:
1 server.port=8989 2 spring.zipkin.base-url=http://localhost:9411 3 spring.application.name=service-miya
接口:
1 import org.springframework.beans.factory.annotation.Autowired; 2 import org.springframework.boot.SpringApplication; 3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4 import org.springframework.context.annotation.Bean; 5 import org.springframework.web.bind.annotation.RequestMapping; 6 import org.springframework.web.bind.annotation.RestController; 7 import org.springframework.web.client.RestTemplate; 8 9 import java.util.logging.Level; 10 import java.util.logging.Logger; 11 12 @SpringBootApplication 13 @RestController 14 public class ServiceMiyaApplication { 15 16 public static void main(String[] args) { 17 SpringApplication.run(ServiceMiyaApplication.class, args); 18 } 19 20 private static final Logger LOG = Logger.getLogger(ServiceMiyaApplication.class.getName()); 21 22 23 @RequestMapping("/hello") 24 public String home(){ 25 LOG.log(Level.INFO, "hello is being called"); 26 return "hello i'm miya!"; 27 } 28 29 @RequestMapping("/miya") 30 public String info(){ 31 LOG.log(Level.INFO, "info is being called"); 32 return restTemplate.getForObject("http://localhost:8988/info",String.class); 33 } 34 35 @Autowired 36 private RestTemplate restTemplate; 37 38 @Bean 39 public RestTemplate getRestTemplate(){ 40 return new RestTemplate(); 41 } 42 }
依次启动上面的三个工程,打开浏览器访问:http://localhost:9411/,会出现以下界面:
访问:http://localhost:8988/hello,浏览器出现:
i'm service-hello
再打开http://localhost:9411/的界面,点击Dependencies,可以发现服务的依赖关系:
点击find traces,可以看到具体服务相互调用的数据:
四、参考资料
利用Zipkin对Spring Cloud应用进行服务追踪分析
五、源码
加入qq群:Spring全家桶技术交流①群196165973,免费获取源码。