ITPub博客

首页 > 数据库 > 数据库开发技术 > Dubbo如何传递链路追踪id?

Dubbo如何传递链路追踪id?

原创 数据库开发技术 作者:hblog 时间:2024-08-30 18:58:58 0 删除 编辑

1.什么是链路追踪?

分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。

链路跟踪主要功能:

  • 故障快速定位:可以通过调用链结合业务日志快速定位错误信息。

  • 链路性能可视化:各个阶段链路耗时、服务依赖关系可以通过可视化界面展现出来。

  • 链路分析:通过分析链路耗时、服务依赖关系可以得到用户的行为路径,汇总分析应用在很多业务场景。

应用场景

在现行微服务的趋势下,一次调用的过程中涉及多个服务节点,产生的日志分布在不同的服务器上,如果需要查看一次调用的全链路日志,则一般的做法是通过在系统边界中产生一个 traceId,向调用链的后续服务传递 traceId,后续服务继续使用 traceId 打印日志,并再向其他后续服务传递 traceId,此过程简称,traceId透传。在使用HTTP协议作为服务协议的系统里,可以统一使用一个封装好的http client做traceId透传。但是dubbo实现traceId透传就稍微复杂些了。一般情况下,会自定义Filter来实现traceId透传。

探寻原理

链路追踪系统(可能)最早是由Goggle公开发布的一篇论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》被大家广泛熟悉,大家感兴趣的话可以去看一看

2.代码工程

前提条件:dubbo工程如何搭建详:Spring Boot集成dubbo快速入门Demo

实验目标

实现消费者和生产者之间传递traceID

消费者

配置过滤器

package com.et.consumer.config;
import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.extension.Activate;import com.alibaba.dubbo.rpc.*;import lombok.extern.slf4j.Slf4j;import org.slf4j.MDC;@Slf4j@Activate(group = {Constants.CONSUMER})public class ConsumerFilter implements Filter {
@Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { Object token = MDC.get("TRACKING_LOG_SESSION_TOKEN_ID"); if (token != null) { log.info("----cunsumer trace id:{}",token); RpcContext.getContext().setAttachment("TRACKING_LOG_SESSION_TOKEN_ID", token.toString()); } Result result = invoker.invoke(invocation); return result; }}

在dubbo-samples-spring-boot-consume/src/main/resources/META-INF/dubbo下面配置过滤器  

ConsumerFilter=com.et.consumer.config.ConsumerFilter

生产者

配置过滤器

package com.et.provider.config;
import com.alibaba.dubbo.common.Constants;import com.alibaba.dubbo.common.extension.Activate;import com.alibaba.dubbo.rpc.*;import lombok.extern.slf4j.Slf4j;import org.slf4j.MDC;
@Slf4j@Activate(group = { Constants.PROVIDER })public class ProviderFilter implements Filter {
@Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
String var = RpcContext.getContext().getAttachment("TRACKING_LOG_SESSION_TOKEN_ID"); MDC.put("TRACKING_LOG_SESSION_TOKEN_ID", var); log.info("----->provider trance id:{}",var); Result result = invoker.invoke(invocation); MDC.remove("TRACKING_LOG_SESSION_TOKEN_ID");
return result; }}

在dubbo-samples-spring-boot-provider/src/main/resources/META-INF/dubbo下面配置过滤器

ProviderFilter=com.et.provider.config.ProviderFilter   

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo(dubbo)

3.测试

  • 启动dubbo-samples-spring-boot-provider

  • 启动dubbo-samples-spring-boot-consume

  • 访问http://127.0.0.1:8080/user/info

消费端日志

2024-08-29 23:46:24.497 [1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA9] [http-nio-8080-exec-1] INFO  c.et.consumer.config.ConsumerFilter [ConsumerFilter.java:16] - ----cunsumer trace id:1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA9

服务端日志

2024-08-29 23:46:24.589 [1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA9] [DubboServerHandler-192.168.0.100:20880-thread-2] INFO c.et.provider.config.ProviderFilter [ProviderFilter.java:18] - ----->provider trance id:1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA92024-08-29 23:46:24.595 [1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA9] [DubboServerHandler-192.168.0.100:20880-thread-2] INFO c.e.provider.service.UserServiceImpl [UserServiceImpl.java:19] - this is a test

实验结果表明traceid【1AB90DBB-06CA-4D35-8A2E-BEDBB4F86DA9】在消费者和服务者之间传递

4.总结

dubbo通过spi和Adaptive注解来实现链路追踪id传递

dubbo的SPI

dubbo在原有的spi基础上主要有以下的改变,①配置文件采用键值对配置的方式,使用起来更加灵活和简单 ② 增强了原本SPI的功能,使得SPI具备ioc和aop的功能,这在原本的java中spi是不支持的。dubbo的spi是通过ExtensionLoader来解析的,通过ExtensionLoader来加载指定的实现类,配置文件的路径在META-INF/dubbo路径下

@Adaptive注解的作用是什么?

Dubbo通过注解@Adaptive作为标记实现了一个适配器类,dubbo将会为这个类动态生成代理对象;ExtensionLoader中获取默认实现类或者通过实现类名称(由@SPI注解指定的名称)来获取实现类 为什么会出现@Adaptive这个注解呢?主要原因是因为dubbo的加载扩展了是从配置文件加载的,是很动态的,但是实现类却要固定写死或者灵活实现,所以就得区分开。用@Adaptive就是表示由框架自己生成,不需要人为实现.在dubbo加载SPI时会动态创建SPI Adaptive实现ExtensionLoader。

  • ExtensionLoader 类里声明了以下几个文件夹都可以使用

private static final String SERVICES_DIRECTORY = "META-INF/services/";private static final String DUBBO_DIRECTORY = "META-INF/dubbo/";private static final String DUBBO_INTERNAL_DIRECTORY = "META-INF/dubbo/internal/";

5.引用

  • https://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html

  • http://www.liuhaihua.cn/archives/711246.html

  • https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/advanced-features-and-usage/service/attachment/

原文作者:HBLOG;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2022-05-04

  • 博文量
    210
  • 访问量
    111727