章节概要:我们使用Spring Cloud搭建的微服务集群,Eureka服务器、Client客户端、Config配置服务器、Zuul网关等节点,都可以横向扩展。一旦集群中的服务数量增多,并且服务之间存在复杂的依赖关系,那么管理这些服务将会变成一件很棘手的事情,为解决以上问题,在微服务架构中实现分布式服务链路追踪变得尤为重要。
概述:Spring Cloud提供了Sleuth框架作为解决方案,Sleuth可以在整个分布式系统中跟踪一个用户请求的过程(包括数据采集,数据传输,数据存储,数据分析,数据可视化等),捕获这些跟踪的数据,并构建微服务的整个调用链的视图,为服务跟踪、解决问题提供便利。
特点:1.提供链路追踪 2.性能分析 3.数据分析 4.可视化
Spring Cloud Sleuth整合Zipkin,我们将微服务产生的日志交给Zipkin去分析,Zipkin是一个分布式追踪系统,主要用于收集、管理微服务产生的数据。Zipkin的设计是基于Google Dapper实现的。在实际应用时,我们需要让各个微服务向Zipkin服务器报告过程数据。
拿之前搭建过的即可
1.依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
<version>2.11.8</version>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<version>2.11.8</version>
</dependency>
</dependencies>
2.application.yml
server:
port: 9411
spring:
application:
name: zipkin-server
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/ #注册中心地址
management:
metrics:
web:
server:
auto-time-requests: false #关闭自动收集web请求
3.在启动类添加@EnableEurekaClient 和 @EnableZipkinServer
@SpringBootApplication
@EnableEurekaClient
@EnableZipkinServer
public class ZipkinServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinServerApplication.class, args);
}
}
1.依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 9410
spring:
application:
name: gateway-service
zipkin:
base-url: http://localhost:9411/
sleuth:
sampler:
probability: 1.0
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
management:
metrics:
web:
server:
auto-time-requests: false
zuul:
routes:
eureka-consumer: #这里记得改
path: /eureka-consumer/**
host:
socket-timeout-millis: 60000
connect-timeout-millis: 10000
3.在启动类添加:@EnableEurekaClient @EnableZuulProxy
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
依赖;
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
</dependency>
<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>
<version>2.1.7.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
</dependencies>
application.yml:
server:
port: 7010
spring:
application:
name: eureka-provider
zipkin:
base-url: http://localhost:9411/
sleuth:
sampler:
probability: 1.0
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
instance:
hostname: localhost
启动类 添加@EnableEurekaClient @RestController,并写暴露接口
@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaProviderApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaProviderApplication.class, args);
}
@GetMapping("/hi")
public String hi(){
return "hello,已经访问到了eureka-provider工程中的hi接口";
}
}
依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.7.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
application.yml:
server:
port: 7011
spring:
application:
name: eureka-consumer
zipkin:
base-url: http://localhost:9411/
sleuth:
sampler:
probability: 1.0
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka/
instance:
hostname: localhost
启动类
@SpringBootApplication
@EnableEurekaClient
@RestController
public class EurekaConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaConsumerApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
@GetMapping("/hi")
public String hi(){
return restTemplate().getForObject("http://eureka-provider/hi",String.class);
}
}
查看是否在eureka服务注册成功
通过网关访问,然后查看ZipKin可视化。
通过单击导航栏中的依赖分析Dependencies选项,可以查看某次请求服务之间的依赖调用关系。
可以看到,客户端先通过网关服务gateway-service调用了生产者eureka-provider,然后eureka-provider调用了消费者eureka-consumer。说明Spring Cloud Sleuth整合Zipkin实现链路追踪成功。
在实际开发中,Zipkin默认展示的链路数据有时无法满足我们想要获取的数据,比如,无法在Zipkin的UI界面中看到请求发送人的名称, 这时,可以使用Zipkin添加自定义链路数据,将请求发送人的名称添加在链路数据中。在本小节中,我们在gateway-service网关服务中添加Zipkin自定义链路数据实现在Zipkin的UI界面中看到请求发送人的名称
在gateway-service项目中新建filter包,并在该包下创建一个LoggerFilter类。
package com.xiaofeng.filter;
import brave.Tracer;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
@Component
public class LoggerFilter extends ZuulFilter {
@Autowired
private Tracer tracer;
@Override
public String filterType() {
return FilterConstants.POST_TYPE;
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
System.out.println(tracer.currentSpan().tag("name","xiaofeng"));
return null;
}
}
依次启动eureka-server、zipkin-server、eureka-provider、eureka-consumer、gateway-service。先使用浏览器访问http://localhost:9410/eureka-provider/service1。在使用浏览器访问http://localhost:9411/,页面会显示 Zipkin服务端的UI界面。在Service Name下拉框选择gateway-service,单击 “Find Trances”按钮,可以看到我们这次请求的节点信息,双击gateway-service服务的节点信息,可以查看gateway-service项目链路的详细信息。