微服务是一团糟的调试工作。在本教程中,我们将发现如何在Spring Cloud环境中调试分布式调用。抽丝剥茧 细说架构那些事——【优锐课】
上篇文章说到,微服务系列详解-Part5:Spring Cloud Zuul代理作为API网关
微服务架构中的挑战之一是调试问题的能力。一个简单的用户操作可能会触发一系列下游微服务调用。在微服务中跟踪与特定用户操作相关的日志将很麻烦。除此之外,我们可能想跟踪为什么某个微服务调用要花费这么多时间。我们可以使用Spring Cloud Sleuth处理此类问题。Spring Cloud Sleuth提供了分布式跟踪功能,我们还可以将这些跟踪信息导出到Zipkin以可视化呼叫跟踪。
在这篇文章中,我们将学习:
• 跟踪分布式服务呼叫
• 使用Spring Cloud Sleuth进行分布式跟踪
• 使用Zipkin服务器进行分布式跟踪
在微服务世界中,用户对UI的操作可能会调用一个微服务API端点,而端点又会调用另一个微服务端点。
例如,当用户看到目录时,shoppingcart-ui将调用目录服务REST API http://localhost:8181/api/products,而产品反过来又调用了库存服务REST API http://localhost:8282/api/inventor以检查库存可用性。
假设发生了异常或返回的数据无效,并且你想通过查看日志来调查问题所在。但是到目前为止,还没有办法将特定用户的日志跨多个服务关联起来。
Poor Man’s分布式追踪
一种解决方案是在调用链的开头,我们可以创建一个CORRELATION_ID并将其添加到所有日志语句中。连同它一起,还将CORRELATION_ID作为标头发送到所有下游服务,以便那些下游服务在日志中也使用CORRELATION_ID。这样,我们可以识别与跨服务的特定操作相关的所有日志语句。
我们可以使用Logging框架的MDC功能来实现此解决方案。通常,我们会有一个WebRequest拦截器,你可以在其中检查是否有CORRELATION_ID标头。如果标题中没有CORRELATION_ID,则创建一个新的并将其设置在MDC中。日志记录框架包括所有日志语句在MDC中设置的信息。
但是,除了我们不做所有这些工作之外,我们还可以使用Spring Cloud Sleuth,它将为我们做所有以及更多的事情。
首先,在这里熟悉Span,Trace,Annotations的一些术语。
让我们将Sleuth启动器添加到库存服务和目录服务中。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
添加Sleuth启动器并启动服务后,你可以在日志中观察到类似以下内容。
2018-03-20 10:19:15.512 INFO [inventory-service,,,] 53685 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver ...
2018-03-20 10:24:15.507 INFO [inventory-service,,,] 53685 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver ...
现在点击任何清单服务REST端点,例如http://localhost:8282/api/inventory。然后,你可以在日志中观察TraceID,SpanID。
2018-03-20 10:15:38.466 INFO [inventory-service,683f8e4370413032,d8abe400c68a9a6b,false] 53685 --- [oryController-3] ...
Sleuth在MDC的日志中包括模式[appname,traceId,spanId,exportable]。
现在,调用目录服务端点http://localhost:8181/api/products端点,该端点在内部调用清单服务端点http://localhost:8282/api/inventory。
在目录服务日志中,你可以找到类似以下内容的日志语句:
`2018-03-20 10:54:29.625 INFO [catalog-service,0335da07260d3d6f,0335da07260d3d6f,false] 53617 --- [io-8181-exec-10]` ...
并且,在清单服务中检查日志,你可以找到类似以下内容的日志语句:
2018-03-20 10:54:29.662 INFO [inventory-service,0335da07260d3d6f,1af68249ac3a6902,false] 53685 --- [oryController-6] ...
请注意,对于同一REST API调用,目录服务和库存服务中的TraceID 0335da07260d3d6f相同。这样,我们可以轻松地将各个服务之间的日志关联起来。
[inventory-service,0335da07260d3d6f,1af68249ac3a6902,false]中的false表示此跟踪未导出到任何跟踪服务器(如Zipkin)。让我们看看如何将跟踪信息导出到Zipkin。
我们学习了如何使用Sleuth在日志中添加跟踪信息。除此之外,我们还可以将该信息导出到Zipkin,以便我们可以通过UI对其进行可视化。
创建Zipkin服务器作为Spring Boot应用程序
我们可以将Zipkin服务器作为Spring Boot应用程序启动,也可以在Docker容器中运行。
到目前为止,Zipkin不支持Spring Boot2。因此,我们可以使用1.5.10.RELEASE版本创建SpringBoot应用程序zipkin-server并添加zipkin-server,zipkin-autoconfigure-ui依赖项。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sivalabs</groupId>
<artifactId>zipkin-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>zipkin-server</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-server</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.java</groupId>
<artifactId>zipkin-autoconfigure-ui</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
将@EnableZipkinServer批注添加到主入口点类。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import zipkin.server.EnableZipkinServer;
@SpringBootApplication
@EnableZipkinServer
public class ZipkinServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZipkinServerApplication.class, args);
}
}
在application.properties中设置端口和应用程序名称。
spring.application.name=zipkin-server
server.port=9411
现在,你可以通过运行ZipkinServerApplication启动Zipkin服务器。
Zipkin服务器作为Docker容器
可以将Docker映像用于OpenZipkin,而不是将Zipkin服务器创建为SpringBoot应用程序。
我们可以使用以下docker-compose-mem.yml文件创建一个由内存数据存储支持的Zipkin服务器。
version: '2'
services:
# The zipkin process services the UI, and also exposes a POST endpoint that
# instrumentation can send trace data to. Scribe is enabled by default.
zipkin:
image: openzipkin/zipkin
container_name: zipkin
# Environment settings are defined here https://github.com/openzipkin/zipkin/tree/1.19.0/zipkin-server#environment-variables
environment:
- STORAGE_TYPE=mem
# Uncomment to disable scribe
# - SCRIBE_ENABLED=false
# Uncomment to enable self-tracing
# - SELF_TRACING_ENABLED=true
# Uncomment to enable debug logging
# - JAVA_OPTS=-Dlogging.level.zipkin=DEBUG
ports:
# Port used for the Zipkin UI and HTTP Api
- 9411:9411
你还可以通过使用https://github.com/openzipkin/docker-zipkin/blob/master/docker-compose.yml使用MySQL数据存储支持的docker映像。
Zipkin服务器启动后,你可以转到http://localhost:9411/以查看Zipkin服务器UI仪表板。
将跟踪信息导出到Zipkin服务器
我们观察到跟踪信息打印在日志中,但没有导出。 我们可以将它们导出到Zipkin服务器,以便在Zipkin Server UI仪表板中可视化跟踪。
将Zipkin Client启动程序添加到库存服务和目录服务。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
在清单服务和目录服务的bootstrap.properties中配置Zipkin服务器URL。
spring.zipkin.base-url=http://localhost:9411/
spring.sleuth.sampler.probability=1
注意:默认情况下,spring.sleuth.sampler.probability = 0.1表示仅将10%的跟踪信息导出到Zipkin。
现在,重新启动清单服务和目录服务,并调用http://localhost:8181/api/products端点。你可以观察到true记录在日志中意味着已导出。
2018-03-20 11:41:02.241 INFO [catalog-service,7d0d44fe314d7758,7d0d44fe314d7758,true] 53617 --- [nio-8181-exec-5] c.s.c.services.ProductService
现在转到Zipkin UI仪表板,你可以在第一个下拉列表中看到填充的服务名称。选择你要检查的服务或全部选中,然后单击“查找跟踪”按钮。
单击任何跟踪,你可以查看每个跨度的呼叫链和等待时间详细信息。
你也可以单击顶部导航栏中的“依赖关系”链接以查看服务依赖关系。
感谢阅读!这个系列就算完结了。
另外还有一些资源分享给各位,需要的可以免费领取~


本文介绍了在微服务环境中使用Spring Cloud Sleuth进行分布式跟踪,并通过Zipkin进行可视化。讲解了如何设置Zipkin服务器,将跟踪信息导出到Zipkin,以及如何在Zipkin UI中查看和分析调用链。
1079

被折叠的 条评论
为什么被折叠?



