使用 Spring Cloud Jaeger 进行分布式跟踪

在本文中,学习如何实现 Jaeger(基于 OpenTracing 和 Spring Boot 应用程序)以及如何使用 Jaeger UI 可视化跟踪。

使用 Spring Cloud Jaeger 进行分布式跟踪

介绍

在本文中,我们将探讨如何使用 Jaeger 实现分布式跟踪以及如何使用 Jaeger UI 可视化跟踪。

Jaeger 是一种开源分布式跟踪机制,有助于跟踪分布式系统中的请求。它基于OpenTracing规范,是云原生计算基金会 (CNCF)的一部分。

有了这个,让我们看一些代码。

实施 Jaeger 跟踪

我们从https://start.spring.io创建一个只有一个“Spring Web”依赖项的应用程序。

生成并下载代码后,我们会将以下 Jaeger 依赖项添加到 pom 文件中,这将有助于在服务之间生成和传播跟踪。

<dependency>
   <groupId>io.opentracing.contrib</groupId>
   <artifactId>opentracing-spring-jaeger-cloud-starter</artifactId>
   <version>3.3.1</version>
</dependency>

有了这个,让我们添加一个带有一些路径的控制器。

@RestController
@RequestMapping("/service")
public class Controller {

    private static final Logger logger = LoggerFactory.getLogger(Controller.class);
    private RestTemplate restTemplate;

    @Value("${spring.application.name}")
    private String applicationName;

    public Controller(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/path1")
    public ResponseEntity path1() {

        logger.info("Incoming request at {} for request /path1 ", applicationName);
        String response = restTemplate.getForObject("http://localhost:8090/service/path2", String.class);
        return ResponseEntity.ok("response from /path1 + " + response);
    }

    @GetMapping("/path2")
    public ResponseEntity path2() {
        logger.info("Incoming request at {} at /path2", applicationName);
        return ResponseEntity.ok("response from /path2 ");
    }
}

在这里,我们有两个端点:/path1和/path2。这里的想法是使用同一应用程序的两个实例,以便在固定端口 8090/path1调用另一个服务。/path2

为了使跨度连接到相同的跟踪 ID,我们需要创建一个 RestTemplate bean 以允许 Jaeger 包含一个拦截器。然后,这有助于向传出请求添加跟踪,这将有助于跟踪整个请求。

@Bean
   public RestTemplate restTemplate(RestTemplateBuilder builder) {
      return builder.build();
   }

完成后,让我们使用 Docker 在本地启动 Jaeger 服务器。为此,我创建了一个带有端口映射的 Docker Compose 文件。

version: "3.3"
services:
  jaeger-allinone:
    image: jaegertracing/all-in-one:1.25
    ports:
      - 6831:6831/udp
      - 6832:6832/udp
      - 16686:16686
      - 14268:14268

我们可以通过 UDP 或 TCP 与 Jaeger 进行通信。使用 启动 Docker 映像后docker-compose up,我们可以使用 URL http://localhost:16686/访问 UI 。

现在,让我们添加一些属性以允许应用程序将跟踪发送到 Jaeger 服务器。我们将通过 TCP 进行通信,因此请确保我们将跟踪发送到另一个 TCP 端口,即 14268

opentracing:
  jaeger:
    http-sender:
      url: http://localhost:14268/api/traces

让我们使用以下命令启动“服务器 1”。

java -jar
target/Distributed-Service-0.0.1-SNAPSHOT.jar
--spring.application.name=Service-1
--server.port=8080

然后在不同的终端上,运行与“服务 2”相同的应用程序的新实例,如下所示

java -jar
target/Distributed-Service-0.0.1-SNAPSHOT.jar
--spring.application.name=Service-2
--server.port=8090

应用程序启动后,调用“Service 1”,/path1如下所示

curl -i http://localhost:8080/service/path1

让我们看一下“服务1”的日志。

INFO 69938 --- [nio-8080-exec-1] i.j.internal.reporters.LoggingReporter   : Span reported: ed70bbaa2bd5b42f:c7c94163fc95fc1e:ed70bbaa2bd5b42f:1 - GET

跟踪的格式为 [Root Span ID, Current Span ID, Parent Span ID]。在这种情况下,由于“服务 1”是发起服务,因此父跨度 IDed70bbaa2bd5b42f也是根跨度 ID。

现在,让我们看一下“服务 2”的日志。

INFO 69885 --- [nio-8090-exec-1] i.j.internal.reporters.LoggingReporter   : Span reported: ed70bbaa2bd5b42f:e9060cb1d5336c55:c7c94163fc95fc1e:1 - path2

从这里我们看到中间值是当前 span ID,父 span ID(即第三个值c7c94163fc95fc1e)是“Service 1”的 span ID。

现在,如果您打开 UI,您将看到以下内容:

使用 Spring Cloud Jaeger 进行分布式跟踪

当我们深入挖掘时,我们会看到每个跨度的更多细节。

使用 Spring Cloud Jaeger 进行分布式跟踪

在这里,根跨度 IDed70bbaa2bd5b42f跨越整个请求。其他两个跨度 ID 指的是单个服务。

结论

今天我们探讨了如何将基于 OpenTracing 的 Jaeger 与 Spring Boot 应用程序集成。您可以点击这里更深入地了解 OpenTracing 的规范。此外,使用 Spring Cloud Jaeger 的库源代码在这里。

我不断探索和学习新事物。如果您想了解最新趋势并提高您的软件开发技能,请关注我。

祝您好运!!

posted @ 2022-02-19 13:21  MicroStone123  阅读(135)  评论(0编辑  收藏  举报