在本文中,学习如何实现 Jaeger(基于 OpenTracing 和 Spring Boot 应用程序)以及如何使用 Jaeger UI 可视化跟踪。
介绍
在本文中,我们将探讨如何使用 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,您将看到以下内容:
当我们深入挖掘时,我们会看到每个跨度的更多细节。
在这里,根跨度 IDed70bbaa2bd5b42f跨越整个请求。其他两个跨度 ID 指的是单个服务。
结论
今天我们探讨了如何将基于 OpenTracing 的 Jaeger 与 Spring Boot 应用程序集成。您可以点击这里更深入地了解 OpenTracing 的规范。此外,使用 Spring Cloud Jaeger 的库源代码在这里。
我不断探索和学习新事物。如果您想了解最新趋势并提高您的软件开发技能,请关注我。
祝您好运!!