Spring Cloud Sleuth集成了追踪组件zipkin组件
微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题,很快定位。
举个例子,在微服务系统中,一个来自用户的请求,请求先达到前端A(如前端界面),然后通过远程调用,达到系统的中间件B、C(如负载均衡、网关等),最后达到后端服务D、E,后端经过一系列的业务逻辑计算最后将数据返回给用户。对于这样一个请求,经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?这就需要用到服务链路追踪。
Google开源的 Dapper链路追踪组件,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这篇文章是业内实现链路追踪的标杆和理论基础,具有非常大的参考价值。目前,链路追踪组件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鹰眼)等,它们都是非常优秀的链路追踪开源组件。
本文主要讲述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin非常的简单,只需要引入相应的依赖和做相关的配置即可。
Spring Cloud Sleuth借用了Dapper的术语。
Zipkin是一种分布式链路追踪系统。 它有助于收集解决微服务架构中的延迟问题所需的时序数据。 它管理这些数据的收集和查找。 Zipkin的设计基于Google Dapper论文。
跟踪器存在于应用程序中,记录请求调用的时间和元数据。跟踪器使用库,它们的使用对用户是无感知的。例如,Web服务器会在收到请求时和发送响应时会记录相应的时间和一些元数据。一次完整链路请求所收集的数据被称为Span。
我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的 API 接口之外,它也提供了方便的 UI 组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。接下来的测试为方便直接采用 In-Memory 方式进行存储,生产推荐 Elasticsearch.
上图展示了 Zipkin 的基础架构,它主要由 4 个核心组件构成:
本文案例一共四个工程, 都是在之前的工程上进行改造
采用官方的jar形式启动,所以需要通过下载官方的jar来启动,也通过以下命令一键启动:
curl -sSL https://zipkin.io/quickstart.sh | bash -sjava -jar zipkin.jar
上面的第一行命令会从zipkin官网下载官方的jar包。如果是window系统,建议使用gitbash执行上面的命令。
如果用 Docker 的话,使用以下命令:
docker run -d -p 9411:9411 openzipkin/zipkin
启动如下
通过java -jar zipkin.jar的方式启动之后,在浏览器上访问lcoalhost:9411,显示的界面如下:
改造eureka-client 工程
加入spring-cloud-starter-zipkin依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
修改配置文件
# 端口号server.port=8762# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=eureka-client#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/
#为true设置的是web开启sleuth功能spring.sleuth.web.client.enabled=true#当设置为1.0时就是链路数据100%收集到zipkin-serverspring.sleuth.sampler.probability=1.0# 指定了 Zipkin 服务器的地址spring.zipkin.base-url=http://localhost:9411
通过引入spring-cloud-starter-zipkin依赖和设置spring.zipkin.base-url就可以了
其中
对外暴露一个Api,方便其他服务调用
package com.li.eurekaclient;
import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication@EnableEurekaClient@RestControllerpublic class EurekaClientApplication {
public static void main(String[] args) { SpringApplication.run(EurekaClientApplication.class, args); }
@Value("${server.port}") String port;
@RequestMapping("/hello") public String home(@RequestParam(value = "name", defaultValue = "lhd") String name) { return "hello: " + name + " ,from port:" + port; }
}
然后分别在feign-server服务,zuul-server服务上加入相同依赖和配置文件即可
依次启动eureka-server, eureka-client, feign-server, zuul-server四个应用,启动完成后,打开浏览器访问http://localhost:8767/feign/hello?name=lhd&token=123 这个是网关调用feign服务的,然后feign调用client的接口,成功响应如下:
这个时候浏览器访问 http://localhost:9411/zipkin/ ,zipkin-server的页面,显示如下:
没有的话点击 Find Traces即可显示
从上图可以看出每次请求所消耗的时间,以及一些span的信息
从上图可以看出具体的服务依赖关系,zuul-server依赖了feign-server依赖了eureka-client
从上图可以看出服务之间的调用的接口以及需要的时间等等
上面的例子是将链路数据存在内存中,只要zipkin-server重启之后,之前的链路数据是全部查找不到的,zipkin是支持将链路数据存储在mysql、cassandra、elasticsearch中的。
后面会讲解如何将链路数据存储在mysql、cassandra、elasticsearch中的
源码下载: https://github.com/LiHaodong888/SpringCloudLearn