使用 Spring Cloud Sleuth 和 Stackdriver Trace 执行分布式跟踪

使用 Spring Cloud Sleuth 和 Stackdriver Trace 执行分布式跟踪

关于此 Codelab

subject上次更新时间:2月 10, 2020
account_circleGoogle 员工编写

1. 概览

要深入了解和观测多层微服务架构,分布式跟踪非常重要。当您将服务到服务的调用串联时(从服务 A 到服务 B 到服务 C),必须了解调用是否成功,还必须每个步骤中的延迟。

在 Spring Boot 中,您可以使用 Spring Cloud Sleuth 将分布式跟踪插桩无缝地添加到您的应用。默认情况下,它可以将跟踪记录数据转发到 Zipkin。

Google Cloud Platform 提供 Stackdriver Trace,这是一项代管式服务,让您无需管理自己的 Zipkin 实例或存储空间即可存储跟踪记录数据。Stackdriver Trace 还可以生成延迟分布报告并自动检测性能下降问题。

您可以通过两种方式在 Spring Boot 应用中使用 Stackdriver Trace:

  1. 使用 Stackdriver Trace Zipkin 代理,并且只需将 Spring Cloud Sleuth 配置为将此代理用作 Zipkin 端点
  2. 或者,使用 Spring Cloud GCP Trace,它与 Spring Cloud Sleuth 无缝集成,并将跟踪记录数据直接转发到 Stackdriver Trace。

在此 Codelab 中,您将学习如何构建新的 Spring Boot 应用以及如何使用 Spring Cloud GCP Trace 进行分布式跟踪。

学习内容

  • 如何创建 Spring Boot Java 应用并配置 Stackdriver Trace。

所需条件

  • 一个 Google Cloud Platform 项目
  • 一个浏览器,例如 ChromeFirefox
  • 熟悉标准的 Linux 文本编辑器,例如 Vim、EMACs 或 Nano

您将如何使用本教程?

您如何评价自己在构建 HTML/CSS Web 应用方面的经验水平?

您如何评价自己在使用 Google Cloud Platform 服务方面的经验水平?

2. 设置和要求

自定进度的环境设置

如果您还没有 Google 帐号(Gmail 或 Google Apps),则必须创建一个。登录 Google Cloud Platform Console (console.cloud.google.com) 并创建一个新项目:

2016-02-10 12:45:26 的屏幕截图.png

请记住项目 ID,它在所有 Google Cloud 项目中都是唯一名称(很抱歉,上述名称已被占用,您无法使用!)。它稍后将在此 Codelab 中被称为 PROJECT_ID

接下来,您需要在 Cloud Console 中启用结算功能,才能使用 Google Cloud 资源。

在此 Codelab 中运行仅花费几美元,但是如果您决定使用更多资源或继续让它们运行,费用可能更高(请参阅本文档末尾的“清理”部分)。

Google Cloud Platform 的新用户有资格获享 $300 免费试用

Google Cloud Shell

虽然 Google Cloud 和 Kubernetes 可以从笔记本电脑远程操作,但在此 Codelab 中,我们将使用 Google Cloud Shell,这是一个在云端运行的命令行环境。

激活 Google Cloud Shell

在 GCP 控制台中,点击右上角工具栏上的 Cloud Shell 图标:

然后点击“启动 Cloud Shell”:

配置和连接到环境应该只需要片刻时间:

这个虚拟机已加载了您需要的所有开发工具。它提供了一个永久性的 5GB 主目录,并且在 Google Cloud 上运行,从而大大增强了网络性能和身份验证功能。只需使用一个浏览器或 Google Chromebook 即可完成本实验中的大部分(甚至全部)工作。

在连接到 Cloud Shell 后,您应该会看到自己已通过身份验证,并且相关项目已设置为您的 PROJECT_ID。

在 Cloud Shell 中运行以下命令以确认您已通过身份验证:

gcloud auth list

命令输出

Credentialed accounts:
 - <myaccount>@<mydomain>.com (active)
gcloud config list project

命令输出

[core]
project = <PROJECT_ID>

如果不是上述结果,您可以使用以下命令进行设置:

gcloud config set project <PROJECT_ID>

命令输出

Updated property [core/project].

3. 创建新的 Spring Boot REST 服务

启动 Cloud Shell 后,您可以使用命令行通过 Spring Initializr 生成新的 Spring Boot 应用:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
 
-d dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
 
-d baseDir=trace-service-one | tar -xzvf - \
 
&& cd trace-service-one

通过添加新类来创建新的 REST 控制器:

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class WorkController {
 
Random r = new Random();

 
public void meeting() {
   
try {
      log
.info("meeting...");
     
// Delay for random number of milliseconds.
     
Thread.sleep(r.nextInt(500));
   
} catch (InterruptedException e) {
   
}
 
}

 
@GetMapping("/")
 
public String work() {
   
// What is work? Meetings!
   
// When you hit this URL, it'll call meetings() 5 times.
   
// Each time will have a random delay.
    log
.info("starting to work");
   
for (int i = 0; i < 5; i++) {
     
this.meeting();
   
}
    log
.info("finished!");
   
return "finished work!";
 
}
}

您可以使用 Spring Boot 插件正常启动 Spring Boot 应用。我们跳过此实验室的测试:

$ ./mvnw -DskipTests spring-boot:run

应用启动后,点击 Cloud Shell 工具栏中的网页预览图标 ,然后选择在端口 8080 上预览

短暂等待后,您应该会看到结果:

在 Cloud Shell 中,您还应该会看到具有跟踪记录 ID 和 span ID 的日志消息:

4. 使用 Stackdriver Trace

启用 Stackdriver Trace API

您需要先启用 Stackdriver Trace API,才能使用 Stackdriver Trace 存储跟踪记录数据。要启用该 API,请导航到 API 服务 → 库

搜索 Stackdriver Trace

点击 Stackdriver Trace API,然后点击启用(如果尚未启用)。

设置应用默认凭据

在本实验室中,您需要配置一个应用默认凭据。Spring Cloud GCP Trace 入门版将会自动获取此凭据。

首先,进行登录:

$ gcloud auth application-default login
You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used
by Application Default
Credentials, so it is not necessary to use this command.
If you decide to proceed anyway, your user credentials may be visible
to others
with access to this virtual machine. Are you sure you want
to authenticate
with your personal account?
Do you want to continue (Y/n)? Y

Go to the following link in your browser:
    https
://accounts.google.com/o/oauth2/auth...
Enter verification code: ...

点击链接以打开新的浏览器标签页,然后点击允许

然后,复制验证码并粘贴回 Cloud Shell,然后按 Enter 键。您应该会看到:

Credentials saved to file: [/tmp/tmp.jm9bnQ4R9Q/application_default_credentials.json]
These credentials will be used by any library that requests
Application Default Credentials.

添加 Spring Cloud GCP Trace

在此服务中,我们已经使用 Spring Cloud Sleuth 进行跟踪。接着来添加 Spring Cloud GCP Trace 入门版,将数据转发到 Stackdriver Trace。

添加 Spring Cloud GCP Trace 依赖项:

pom.xml

<project>
  ...
 
<dependencies>
    ...
   
<!-- Add Stackdriver Trace Starter -->
   
<dependency>
     
<groupId>org.springframework.cloud</groupId>
     
<artifactId>spring-cloud-gcp-starter-trace</artifactId>
   
</dependency>
 
</dependencies>
  ...
</project>

默认情况下,Spring Cloud Sleuth 不会对每个请求进行采样。为便于我们的测试,请将 application.properties 中的采样率提高至 100%,以确保我们能看到跟踪记录数据,并忽略一些我们不关心的网址:

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
"
> src/main/resources/application.properties

再次运行应用,并使用 Cloud Shell 网页预览来查看应用:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$
./mvnw -DskipTests spring-boot:run

默认情况下,Spring Cloud GCP Trace 会对跟踪记录数据进行批处理,并每 10 秒或在收到一定数量的跟踪记录数据时发送一次。这是可配置的。如需了解详情,请查看 Spring Cloud GCP Trace 参考文档

向服务发出请求:

$ curl localhost:8080

在 Cloud Console 中,导航到 StackdriverTrace跟踪记录列表

在顶部将时间范围缩短为 1 小时。默认情况下,自动重新加载处于开启状态。因此,一旦跟踪记录数据到达,它就会显示在控制台中!

跟踪记录数据应会在大约 30 秒内显示。

点击蓝色点可查看跟踪记录详情:

这非常简单!

5. 创建第二个 Spring Boot Web 应用

点击 + 图标,打开一个新的 Cloud Shell 会话:

在新会话中,创建第二个 Spring Boot 应用:

$ curl https://start.spring.io/starter.tgz -d packaging=jar \
 
-d dependencies=web,lombok,cloud-gcp,cloud-starter-sleuth \
 
-d baseDir=trace-service-two | tar -xzvf - \
 
&& cd trace-service-two

通过添加新类来创建新的 REST 控制器:

src/main/java/com/example/demo/MeetingController.java

package com.example.demo;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

@RestController
@Slf4j
public class MeetingController {
 
Random r = new Random();

 
@GetMapping("/meet")
 
public String meeting() {
   
try {
      log
.info("meeting...");
     
Thread.sleep(r.nextInt(500 - 20 + 1) + 20);
   
} catch (InterruptedException e) {
   
}
   
return "finished meeting";
 
}
}

将 Spring Cloud GCP Trace 添加到 pom.xml

pom.xml

<project>
  ...
 
<dependencies>
    ...
   
<!-- Add Stackdriver Trace starter -->
   
<dependency>
     
<groupId>org.springframework.cloud</groupId>
     
<artifactId>spring-cloud-gcp-starter-trace</artifactId>
   
</dependency>
 
</dependencies>
  ...
</project>

配置 Sleuth 来对请求进行 100% 采样:

src/main/resources/application.properties

$ echo "
spring.sleuth.sampler.probability=1.0
spring.sleuth.web.skipPattern=(^cleanup.*|.+favicon.*)
"
> src/main/resources/application.properties

最后,您可以使用 Spring Boot 插件在端口 8081 上启动 Spring Boot 应用:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$
./mvnw -DskipTests spring-boot:run -Dserver.port=8081

6. 更新第一个服务以使用第二个服务

trace-service-two 运行期间,返回到第一个 Cloud Shell 会话窗口并修改 trace-service-one

首先,初始化新的 RestTemplate Bean:

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

...

import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class DemoApplication {
       
@Bean
       
public RestTemplate restTemplate() {
               
return new RestTemplate();
       
}

       
public static void main(String[] args) {
               
SpringApplication.run(DemoApplication.class, args);
       
}
}

WorkController.meeting() 中,向会议服务拨打电话。

src/main/java/com/example/demo/WorkController.java

package com.example.demo;

...
import org.springframework.web.client.RestTemplate;
import org.springframework.beans.factory.annotation.Autowired;

@RestController
@Slf4j
public class WorkController {
 
@Autowired
 
RestTemplate restTemplate;

 
public void meeting() {
   
String result = restTemplate.getForObject("http://localhost:8081/meet", String.class);
    log
.info(result);
 
}

 
...
}

再次启动该服务,并通过网页预览来触发端点:

$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$
./mvnw -DskipTests spring-boot:run

在两个会话窗口中,您都应该会看到日志消息,其中跟踪记录 ID 已从一项服务传播到另一项服务。

在 Stackdriver Trace 的“跟踪记录列表”中,您应该会看到第二条跟踪记录:

您可以点击新的蓝色点来查看跟踪记录详情:

您还可以点击此图表中的任意 span 来查看 span 的详细信息。

7. 延迟时间分布情况和效果报告

将 Stackdriver Trace 用作跟踪记录数据存储时,Stackdriver Trace 可以使用这些数据来构建延迟分布报告。为了构建这种报表,您需要使用 100 条以上的跟踪记录:

此外,Stackdriver Trace 可在分析报告下自动检测同一服务在两个不同时间段内的性能下降情况。

8. 总结

在本实验室中,您创建了 2 项简单的服务,通过 Spring Cloud Sleuth 添加了分布式跟踪记录,还使用 Spring Cloud GCP 将跟踪记录信息转发到了 Stackdriver Trace。

9. 恭喜!

您已了解如何编写您的第一个 App Engine Web 应用!

了解详情

许可

此作品已获得 Creative Commons Attribution 2.0 通用许可授权。