上一章 SpringCloud 基础教程(十)-Zuul 服务网关当中,我们了解了Zuul在微服架构中担任着重要的网关角色,并实现了一个简单的Token过滤。本章我们将介绍另一个服务组件Spring Cloud Sleuth。
前言
在微服务系统中,业务的调用多数不是在一个进程中实现的,可以知道,随着服务的拆分,微服务组件是越来越多,每个模块都是不同的人维护,一个请求会涉及多个服务协调的处理,那么当出现故障时,如何快速的定位线上的故障呢?
比较成熟的方案是通过调用链的方式,把一个用户的请求串联起来。Sping Cloud Sleuth是一个分布式的调用链跟踪工具:
一、快速开始
1.1 准备工作
在我们之前的章节中,我们有了以下的服务组件:
- Eureka注册中心:eureka-server
- 服务消费者1个server-consumer
- 服务提供者2个server-provider
1.2 如何开始
我们在服务消费者server-consumer、服务提供者server-provider和eureka-server引入sleuth依赖,并启动注册中心、服务提供者和服务消费者:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
服务消费者server-consumer控制器,helloApi是Feign编写的接口,注入调用:
@RestController
@RequestMapping("/hystrix")
public class HystrixController {
private final Logger logger = LoggerFactory.getLogger(HystrixController.class);
@Autowired
HelloApi helloApi;
@RequestMapping("/sayHello")
@HystrixCommand(fallbackMethod = "sayError")
public String sayHello(String name) {
return helloApi.sayHello(name);
}
@RequestMapping("/sayHello")
@HystrixCommand(fallbackMethod = "sayError")
public String sayHello(String name) {
logger.info("server-consumer :{}" name);
return helloApi.sayHello(name);
}
服务提供者server-provider控制器:
@RestController
public class RibbonController {
private final Logger logger = LoggerFactory.getLogger(RibbonController.class);
@Value("${server.port}")
private String port;
@RequestMapping("/sayHello")
public String sayHello(String name) {
logger.info("server-provider :{}" name);
return "from:" port ",hello!," name;
}
启动程序后,然后通过HTTP方式调用接口 http://localhost:5168/hystrix/sayHello?name=name,接口正确返回结果,同时我们可以看到后台日志:
服务消费者日志:
2020-01-30 22:34:30.118 INFO [server-consumer,ef944d0faefb97cd,c72e13f0bd0a4398,false] 10904 --- [rixController-1] c.m.consumer.test.HystrixController : server-consumer :{}name
服务提供者日志:
2020-01-30 22:34:30.366 INFO [server-provider,ef944d0faefb97cd,aef54537badf8ea0,false] 22664 --- [nio-9001-exec-1] c.m.provider.RibbonController : server-provider :{}name
可以看到日志信息多出了很多信息如: [server-consumer,ef944d0faefb97cd,c72e13f0bd0a4398,false],
- server-consumer:应用名称
- ef944d0faefb97cd:一个TraceId,这里的服务提供者和服务调用者的TraceID是一样的
- c72e13f0bd0a4398:一个SpanId
二、Spring Cloud Sleuth 介绍
在引入spring-cloud-starter-sleuth依赖后,客户端的每一次请求,都会生成这样的日志,Spring Cloud Sleuth借用了Dapper的术语:
- Span:最小的工作单元,发送一个RPC请求或者响应一个RPC请求也是一个新的Span,SpringCloud Sleuth会为其生成一个64位的全局唯一的ID,包括了时间、标签、SpanID,进程ID(IP)。
- Trace:理解为一个完整的调用链请求
- Annotation :用来及时记录时间的存在,用一些重要的注解定义请求的开始和结束
1 、cs Client-Request 客户端发送请求,描述一个Span的开始
2 、sr Server Recoived 服务端接受请求,并开始处理
3 、ss Server Sent 表示请完成
4 、cr Client- Received 表示Span的结束
可以用图的形式表示一次调用链的实例:
从图中我们可以看到,一次完整的用户请求,TraceID是不变的,不管中间经过了多少的服务,TraceID是唯一确定的。而SpanId的变化是发生了RPC请求。这样我们就可以更具这些信息,如果让生为了故障,我们就可以追踪具体的服务组件了。
三、总结
本章我们简单介绍了在分布式环境下,我们该用什么样的方法快速的定位服务的故障,了解了Spring Cloud Sleuth的简单概念,以及如何在项目中应用,当然仅仅收集这些日志信息是不够的,我们需要的把它给收集起来,通常Spring Cloud Sleuth会打印日志聚集值Zipkin中,有Zipkin收集、存储、提供查询等。接下来我们会介绍如何在Spring Cloud生态下集成Zipkin。
----END----