聊聊 SpringBoot3 的 Micrometer Tracing

这是个很尴尬的话题,为什么这么说呢?当我们在讨论卷和造轮子两个事情的时候,SpringBoot 的开发人员也正在做着同样的事情...

回顾

之前在 微服务-分布式链路 这篇文章中我介绍了 Dapper、OpenTracing,并以蚂蚁分布式链路组件 SOFATracer 为例,较为详细的说明了分布式链路组件中的一些技术细节和实现方式,有兴趣的同学可以自行查看。

Micrometer Tracing

最近关注 SpringBoot3 的发布,在 Production-ready Features 中,首次将 tracing 作为一个单独的功能项写进官方文档中;在此之前 SpringBoot 仅提供了 Http Tracing 的能力,并且默认情况下,是在内存中存储 近 100 次请求的记录;在 2.7.x 的官方文档中,Http Tracing 只是建议在开发环境使用,对于生产环境,官方文档也明确的指出,建议使用 Zipkin 或 Spring Cloud Sleuth 这类比较成熟的可观测性解决方案。

从 Dapper 到 OpenTracing,解决了厂商无关和统一链路 API 的问题,从 OpenTracing 到 OpenTelemetry,解决统一可观测性 API 的问题,并且 OpenTelemetry2019-5.7 被 CNCF Accepted 之后,也在不断地孵化和完善。如果说 SpringBoot 面向 OpenTelemetry 提供 Tracing,可能更便于接受,但是 SpringBoot 却使用了 Micrometer tracing,并且通过 Facade 进行了桥接 Brave 和 otel。

首先一点是,SpringBoot 将 Tracing 在 v3 系列提供出来比较容易理解,在可观测性上,tracing 一直都是 SpringBoot 缺失的,在 SpringCloud 中,它通过 Spring Cloud Slueth 整合了 Brave 补缺了这一环。

比较疑惑的是,SpringBoot 提供的 tracing 为什么会选择使用一个新的 facade Micrometer tracing 来实现,这一点我尝试从 issue 中去找答案,但也没有找到比较有说服力的,比如 Add auto-configuration for Micrometer 2.0 Observation APIAdd support for Micrometer tracing。不过有意思的是,在 https://spring.io/projects/spring-cloud-sleuth 这里给出了一些信息,意思就是 Spring Cloud Slueth 将迁移到 Micrometer tracing

那么关于为什么 SpringBoot 使用 Micrometer 而不是 OpenTelemetry,可能有以下几点原因(一家之言,欢迎指导): * 1、在之前的一些版本中,Micrometer 关注更多是 metrics,而 OpenTelemetry 则更多关注 tracing,但是随着版本的迭代完善,Micrometer 和 OpenTelemetry 在 metrics 和 tracing API 上基本都具备了。重要的是,在此之前,SpringBoot 已经对 Micrometer Metrics 进行了支持,所谓近水楼台先得月。 * 2、OpenTelemetry 的目标是厂商无关,语言无关,penTelemetry 更适合在异构技术栈中发挥作用而 Micrometer 一直以来都是基于 Java 语言,这与 Spring 体系从根上是一致的。 * 3、Micrometer API 进行大量更改。最重要的变化是引入了一个新的 API:Observation API,这样便于使用者能够使用统一的 API 来观测业务代码,包括 metrics, tracing 以及 logging。

下面就 SpringBoot3 Tracing 展开聊聊。

SpringBoot3 Tracing 剖析

SpringBoot3 在 Spring Boot Actuator 中为 Micrometer Tracing 的依赖性管理和自动配置。Micrometer Tracing 充当了类似日志领域内 slf4j 门面的角色。

Micrometer Tracing API

Micrometer Tracing 中的相关概念也是借用 Dapper 的,比如 SpanTrace 等,这里不做过多介绍。总体来说,Micrometer Tracing 包括以下几个部分: * 核心模块主要包含 instrumentation SPI * 用于适配其它 tracing 实现的 bridge 桥接器 * 用于上报 span 数据的 reportor 扩展机制 * 测试模块

功能划分和代码模块结构组织是一致的

image.png

在 Micrometer Tracing 中,一个完整的 tracing 大致如下图所示

image.png

bridge 桥接器

当前版本,Micrometer Tracing 支持两种 Tracers * OpenZipkin Brave * OpenTelemetry

在使用时,你只能选择一个 bridge 桥接实现,如果在你的 classpath 中包括两个,可能会有一些意想不到的问题,比如重复的 trace 或者 span。

Reporters

当前版本,Micrometer Tracing 支持两种 Reporters

如何和 Brave 集成的

不管是 brave 还是 otel,它们都是完整的分布式链路解决方案,包括 API 和 instrumentation;Micrometer Tracing 与 brave、otel 的集成是典型的 接口继承 + 委托 的形式实现的,以 span 为例: ```java import io.micrometer.tracing.Span;

/** * Brave implementation of a {@link Span}. * * @author Marcin Grzejszczak * @since 1.0.0 */ public class BraveSpan implements Span {

final brave.Span delegate;
// 省略其它无关代码 ...

} ```

这种方式也是 skywalking、zipkin-brave、sofatracer1.0、jaeger 等组件在早期支持 opentrcing API 的实现方式。

如何上报给 zipkin 的

我在 原理 | 分布式链路跟踪组件 SOFATracer 和 Zipkin 模型转换 这篇文章中介绍过 SOFATracer 是如何将 span 数据上报给 zipkin 的,它的做法是:在 span 结束的时候,通过预留的 reporter 扩展机制,使得用户可以通过自定义 reporter 来实现 span 数据的上报。两个关键点: * 上报时机:span 结束时 * 上报方式:通过自定义 reporter 上报

Micrometer Tracing 本身包括了对 span 完整生命周期管理的 API ```java /** * Starts this span. * @return this span */ Span start();

/** * Ends the span. The span gets stopped and recorded if not noop. */ void end();

/** * Ends the span. The span gets stopped and recorded if not noop. * @param time timestamp * @param timeUnit time unit of the timestamp */ void end(long time, TimeUnit timeUnit); `` 因此上报时机都是一样的,在 span 结束时发生。上报方式,Brave 提供了一个 SpanHandler 扩展接口,对应的具体实现是ZipkinSpanHandler,otel 中提供的是SpanExporter扩展接口,对应的实现是ZipkinSpanExporter`。下面用一张简单的图描述下

image.png

a simple guides for you

这里给一个小案例,主要是官方文档中并没有提供 step by step 的集成方式。以 Micrometer tacing + brave + zipkin 的方式为例。

依赖

  • 增加依赖,下面给出的依赖均为必须提供的 ```xml org.springframework.boot spring-boot-starter-actuator

    io.micrometer micrometer-tracing

    io.micrometer micrometer-tracing-bridge-brave io.zipkin.reporter2 zipkin-reporter-brave

io.micrometer micrometer-tracing-bom 1.0.0 pom import ```

提供一个测试 REST API

java @RequestMapping("api") @RestController() public class MyController { private static final Log logger = LogFactory.getLog(MyController.class); @RequestMapping("test") public String test() { // 配置了在日志中输出 traceId logger.info("this is test log ...."); return "SUCCESS"; } }

基本配置

```

采样比率

management.tracing.sampling.probability=1.0

将 traceId 和 spanId 和 log 绑定

logging.pattern.level=%5p [${spring.application.name:test},%X{traceId:-},%X{spanId:-}]`

```

测试

访问 curl http://localhost:8080/api/test

  • 日志输出如下: json 2022-12-06T12:06:36.971+08:00 INFO [test,638ebfccd315f7022e7eee028343517f,2e7eee028343517f] 61043 --- [nio-8080- exec-1] c.g.bridge.boot.controller.MyController : this is test log ....

  • zipkin 界面

image.png

PS:你可能没有看到任何关于 zipkin 的配置,因为默认情况下,zipkin 的上报地址是 127.0.0.1:9411,我在本地通过 docker 启动了一个 zipkin 实例,所以我并不需要做额外的配置。

总结

本篇对 SpringBoot3 tracing 做了一些介绍,通过本篇文章,希望你可以了解到 SpringBoot3 中提供 tracing 的初衷,以及在众多事实标准存在情况下选择 Micrometer tracing 作为 API 的原因。这篇文章并不会涉及到过多对于 tracing 基础概念的介绍,如果你有兴趣可以自行查阅。最后我给出了 Micrometer tacing + brave + zipkin 一个小案例,希望可以帮助到你。

本文正在参加「金石计划 . 瓜分6万现金大奖」

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

glmapper_2018

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值