分布式追踪:SpringBoot 3.x + MDC

原创 梁波Eric Eric技术圈 2024年08月15日 09:18 四川

图片

如果不想引入第三方组件,比如:Sping Cloud Sleuth ,可以采用轻量级的解决方案来完成分布式系统下的日志链路追踪。

同时本文主要聚焦在日志的链路追踪,服务之间的调用链路追踪,可采用工具实现,比如:Jaeger、Zipkin、SkyWalking、Pinpoint、Elastic APM 等。

问题

Spring 默认的日志框架 Logback 中提供的 LogbackMDCAdapter 内部使用的是ThreadLocal,只有本线程才有效,子线程和下游的服务 MDC 里的值会丢失。

主要的难点是解决值传递问题,主要包括以下几个部分:

  • API Gateway 网关中如何传递 MDC 中的 TraceId

  • 微服务之间互相远程调用时如何传递 MDC 中的 TraceId

  • 异步情况下(线程池)如何传递 MDC 中的 TraceId 到子线程

  • ........

环境准备

技术选型:

  • Java 21

  • Spring Boot 3.2.4

  • Spring Cloud 2023.0.1

  • Spring Cloud Gateway 4.1.2

  • Spring Cloud OpenFeign 4.1.1

  • Alibaba Transmittable Thread Local 2.14.5

01 API Gateway 网关

创建一个 GlobalTraceFilter 进行 Web 请求 和 路由请求的 TraceId 过滤处理,参考:

图片

配置 Logback 文件 logback-spring.xml:

图片

 
  1. <springProperty scope="context" name="appName" source="spring.application.name"/>

  2. <property name="CONSOLE_LOG_PATTERN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(%level){blue} %clr(${PID}){magenta} %clr([%X{traceId:-}]){yellow} %clr([${appName}]){blue} %clr([%thread]){orange} %clr(%-40.40logger{39}){cyan} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

02 下游微服务拦截 Http Header

解析 Http 请求 Header 中的 TraceId,可以看到由第一步 Api Gateway 设置的。创建一个

图片

03 下游微服务互相调用

创建 OpenFeign Interceptor ,下游服务之间的相互调用统一使用 FeignClient 进行调用。

图片

04 异步多线程传递问题

改造 LogbackMDCAdapter

将 LogbackMDCAdapter 重新拷贝使用阿里巴巴的 TransmittableThreadLocal 替换 ThreadLocal,来解决多线程无法传递 MDC 值问题。

SpringBoot 3.0 以上版本后,无法替换 Logback 的 MDC Adapter,需要将我们新建的 MDC Adapter配置到spi文件中,参考下图 META-INFO下services 目录中的SLF4JServiceProvider。

图片

成功后日志输出如下:

图片

但是每次启动都会有类似的错误提醒,后续看下是否可以优化。

替换 Spring 默认线程池

同理也是使用 alibaba 的 TtlRunnable进行替换。

图片

小结

随着系统管理的服务数量的不断增加,了解系统在生产环境的状态愈发困难,同时也导致排查问题故障变得更加困难,建议在考虑采用微服务架构之前,将日志聚合和分布式追踪作为先决条件。

附录

Gateway 改造 MDC 后验证:

图片

图片

下游服务调用:

1)通过 Gateway 请求下游服务

图片

图片

2)下游服务日志查看 TraceId

图片

可观测性( Elastic Stack ):

关于如何部署可视化工具,参考公众号之前 Elastic 可观测性系列文章。

图片

图片

Spring Cloud Sleuth:

图片

根据提供的引用内容,报错信息如下: \[1\] { "timestamp": "2022-05-27T10:39:14.562+00:00", "status": 404, "error": "Not Found", "path": "/books/1" } \[2\] {“timestamp”:1623317106890, “status”:404, “error”:“Not Found”, “message”:"", “path”:"/api/mdc/factory/standard_text/update" } \[3\] { "timestamp": "2022-06-29 11:20:48+08:00", "status": 403, "error": "Forbidden", "message": "", "path": "/api/login.json" } 根据提供的错误原因,无法确定具体的错误原因。请提供更多的上下文信息或者详细描述问题,以便我能够更好地帮助您解决问题。 #### 引用[.reference_title] - *1* [Springboot运行报错: “status“: 404, “error“: “Not Found](https://blog.csdn.net/m0_51426055/article/details/125009229)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [运行spring boot项目 报错{“timestamp“:16524, “status“:404, “error“:“Not Found“, “message“:...](https://blog.csdn.net/ccpshare/article/details/117787347)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [记一次spring security403错误:{“timestamp“:“2022-06-30 14:05:32“,“status“:403,“error“:...](https://blog.csdn.net/weixin_42675423/article/details/125540152)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值