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,可以看到具体服务相互调用的数据:

四、参考资料

 spring-cloud-sleuth

利用Zipkin对Spring Cloud应用进行服务追踪分析

五、源码

 加入qq群:Spring全家桶技术交流①群196165973,免费获取源码。

原文地址:https://www.cnblogs.com/51ma/p/12916617.html