什么是分布式追踪
微服务的主要挑战之一是调试问题和监视问题的能力。一个简单的操作可以触发一系列的微服务调用,在被调用的微服务中跟踪这些操作是非常繁琐的。这是因为每个微服务都在与其他微服务隔离的环境中运行,因此它们不会共享数据库或日志文件等资源。除此之外,我们可能还需要跟踪为什么某个微服务调用在给定的业务流中花费了如此多的时间。
分布式跟踪模式解决了开发人员在构建微服务时面临的上述挑战。在使用Spring Boot和Spring Cloud框架创建微服务时,有一些有用的开源工具可用于分布式跟踪。
Spring Cloud Sleuth: 一个Spring Cloud库,通过在HTTP请求头文件上添加trace和span id,可以跟踪后续微服务的进度。该库基于MDC(映射诊断上下文)概念,可以轻松提取放入上下文中的值并将它们显示在日志中。
Zipkin: 基于java的分布式跟踪应用程序,帮助收集独立服务之间传播的每个请求的时间数据。它有一个简单的管理控制台,我们可以在其中看到后续服务生成的时间统计信息的可视化。
ELK栈: 三个开源工具- Elasticsearch, Logstash和Kibana组成了ELK栈。它们用于实时搜索、分析和可视化日志数据。Elasticsearch是一个搜索和分析引擎。Logstash是一个服务器端数据处理管道,它同时从多个源获取数据,对其进行转换,然后将其发送给Elasticsearch存储。Kibana让我们用图表和图形来可视化这些数据。
如何把他们整合到一起工作
当进行HTTP调用时,该调用被Sleuth截获,并将必要的标记添加到请求头中。服务接收到HTTP响应后,将数据异步发送到Zipkin,以防止与跟踪系统相关的延迟或故障延迟或破坏流。
Sleuth将两种类型的ID添加到日志文件中,一种称为trace ID,另一种称为span ID。span ID表示基本的工作单元,例如发送HTTP请求。trace ID包含一组span ID,形成树状结构。当一个微服务调用下一个微服务时,trace ID将保持不变。
为方便起见,本例中的日志直接发布到Logstash,但是我们也可以使用Beats。Beats是一个简单的数据传送器,它要么位于服务器上,要么位于容器上,监听日志文件的位置,然后将它们发送到Logstash进行转换,或发送到Elasticsearch。
安装
1. 安装Zipkin
curl -sSL https://zipkin.io/quickstart.sh | bash -sjava -jar zipkin.jar
通过访问http://localhost:9411/zipkin/ 上的Zipkin web接口来验证设置。
2. 安装ELK栈
在官网下载ELK, https://www.elastic.co/cn/start
$ bin/elasticsearch
$ bin/kibana
创建 logstash-microserver.conf 文件
input {
tcp {
port => 5044
}
}
filter {
json {
source => "message"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
manage_template => false
index => "logstash-local"
}
}
端口5601上启动Kibana,在端口9200上启动ElasticSearch,在端口5044上启动LogStash。
通过访问 http://localhost:5601 上的web控制台来验证kibana设置。
使用下面的curl命令验证Elasticsearch
至此,所有安装完成!
项目实战
创建3个微服务
microserver-amanda(28081)
microserver-bastone (28082)
microserver-cospa (28083)
修改 pom.xml
添加Sleuth和Zipkin依赖, 同时添加logstashd的logback依赖。
<!-- Zipkin and Sleuth -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<!-- 添加了Zipkin的话,Sleuth可以不用重复依赖了 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- Dependencies for LogStash -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>5.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
配置 application.properties
推送数据到Zipkin
# Zipkin info
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1
修改 logback.xml
推送日志到Logstash。appender使用异步TCP将运行在端口5044上的所有日志发布到Logstash。同样,Beats也可以用于将日志发送到Logstash。
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:5044</destination>
<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<mdc/>
<context/>
<version/>
<logLevel/>
<loggerName/>
<message/>
<pattern>
<pattern>
{
"appName": "microserver-amanda"
}
</pattern>
</pattern>
<threadName/>
<stackTrace/>
</providers>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="logstash"/>
</root>
<logger name="org.springframework" level="INFO"/>
<logger name="com.explore" level="INFO"/>
</configuration>
所有需要使用分布式跟踪功能的服务,都需要按上面的就行修改配置。
运行所有服务
在kibana上创建index,名叫logstash-local
,可通过过滤条件查看所有日志。
zipkin显示的链路追踪图