微服务结构是一个分布式架构,微服务系统按照业务划分服务单元,一个微服务系统往往有很多个服务单元。由于服务单元数量众多,服务单元之间的调用很复杂,一旦出现错误和异常,很难去定位。所以在微服务架构中必须实现分布式服务链路追踪。目前,常见的链路追踪组件有Google的Dapper,Twitter的Zipkin,以及阿里的Eagleeye(鹰眼)等,它们都是非常优秀的链路追踪开源组件。
本章主要讲述如何在Spring Cloud Sleuth中集成Zipkin。
如果一个服务的调用关系如下:
那么此时将Span和Trace在一个系统中使用Zipkin注解的过程图形化:
每个颜色的表明一个Span(总计7个Spans,从A到G),每个Span有类似的信息:
Trace Id = X
Span Id = D
Client Sent
此Span表示Span的Trance Id是X,Span Id是D,同时它发送一个Client Sent事件。
服务 | 端口 | 服务说明 |
---|---|---|
eureka | 8761 | 服务注册于发现 |
provider | 8800 | 服务提供者 |
consumer | 8801 | 服务消费者 |
chainMonitor | 8770 | 链路追踪服务端 |
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
<dependency>
<groupId>io.zipkin.javagroupId>
<artifactId>zipkin-autoconfigure-uiartifactId>
<version>2.11.5version>
dependency>
<dependency>
<groupId>io.zipkin.javagroupId>
<artifactId>zipkin-serverartifactId>
<version>2.11.5version>
dependency>
server:
port: 8770
spring:
application:
name: chainmonitor
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
management:
metrics:
web:
server:
auto-time-requests: false
@EnableZipkinServer
@SpringBootApplication @EnableEurekaClient @EnableZipkinServer public class ChainmonitorApplication { public static void main(String[] args) { SpringApplication.run(ChainmonitorApplication.class, args); } }
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zipkinartifactId>
dependency>
server:
port: 8800
spring:
application:
name: provider
# zipkin的地址:通过真实IP地址访问
zipkin:
base-url: http://localhost:8770
#通过服务名访问
#base-url: http://chainmonitor/
sleuth:
sampler:
#设置采样率,为了测试设置100%采集,设置为1.0
probability: 1.0
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
@RestController public class HelloController { @RequestMapping(value = "/getBookByName") public String getNameById(@RequestParam("id") String id){ String bookName = ""; switch (id){ case "1" : bookName = "Java"; break; case "2" : bookName = "C++"; break; default: bookName = "phython"; } return bookName; } }
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-zipkinartifactId>
dependency>
server:
port: 8801
spring:
application:
name: consumer
# zipkin的地址:通过真实IP地址访问
zipkin:
base-url: http://localhost:8770
#通过服务名访问
#base-url: http://chainmonitor/
sleuth:
sampler:
#设置采样率,为了测试设置100%采集,设置为1.0
probability: 1.0
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
@FeignClient(name = "provider") public interface FeignService { @RequestMapping(value = "/getBookByName",method = RequestMethod.GET) String getBookByName(@RequestParam("id") String id); }
@RestController public class HelloController { @Autowired private FeignService feignService; @RequestMapping(value = "getBookName") public String getBookName(@RequestParam("id") String id){ return feignService.getBookByName(id); } }
在Zipkin中展示了跟踪信息,红框里是一个Trace
点击每个Trace,可以看到多个Span
点击每个span,可以看到详细信息
如果调用链路中发生接口调用失败,zipkin会默认使用红色展示信息,如下图:
点击红色的span,可以看到详细的失败信息:
github示例代码下载