springboot+dubbo整合sleuth+zipkin实现链路追踪


目录

  1.项目背景

  2.整体架构图

  3.链路效果

    1.返回数据

    2.zipkin效果

  4.技术实现

    1.pom依赖

    2.在springweb项目中添加 traceId

    3.在logback中添加 traceId

    4.zipkin搭建

项目背景

  在搭建新的springcloud + dubbo 项目框架的时候,负责实现全局链路追踪,从请求通过网关到最后通过网关返回数据有一个全局的 TraceId 可以追踪

  1.前端可看到 TraceId 

  2.业务日志能看到 TraceId 

  3.在zipkin中能检索到 TraceId 走过的链路信息

  4.能够做到全程不需要人工编码参与

整体项目架构

 

实现原理:在各个服务的入口处添加过滤器,http请求和dubbo都一样,设置TraceId,通过上下文在当前项目中传递

3.链路效果

  1.返回数据

{
    "code": "00000",
    "data": {
        "looked": 0
    },
    "message": "SUCCESS",
    "page": null,
    "traceId": "588f31cbe8319733"
}

  2.zipkin效果

 

 

 

 

4.技术实现

1.pom依赖

<!--zipkin依赖中包含了sleuth依赖-->
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> <version>2.2.5.RELEASE</version> </dependency> <dependency> <groupId>io.zipkin.brave</groupId> <artifactId>brave-instrumentation-dubbo</artifactId> <version>5.12.6</version> </dependency>

2.在springweb项目中添加 traceId

  在统一的返回实体中给 traceId字段赋值

//统一返回实体
public
class Result<T> implements Serializable { private static final long serialVersionUID = -8373949364192372417L; private String code; private String message; private T data; private Page page; private String traceId; }
import brave.Tracer;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * 初始化 {@linkplain HandlerMethodReturnValueHandlerProxy} 注入参数 Tracer并代理 {@linkplain HandlerMethodReturnValueHandler}
 * 添加到 handlerAdapter.getReturnValueHandlers()中
 */
@Configuration
public class RestReturnValueHandlerConfig implements InitializingBean {
    @Resource
    private RequestMappingHandlerAdapter handlerAdapter;
    @Resource
    private Tracer trace;

    @Override
    public void afterPropertiesSet() {List<HandlerMethodReturnValueHandler> list = handlerAdapter.getReturnValueHandlers();
        List<HandlerMethodReturnValueHandler> newList = new ArrayList<>();
        if (list != null) {
            for (HandlerMethodReturnValueHandler valueHandler : list) {
                if (valueHandler instanceof RequestResponseBodyMethodProcessor) {
                    HandlerMethodReturnValueHandlerProxy proxy = new HandlerMethodReturnValueHandlerProxy(valueHandler, trace);
                    newList.add(proxy);
                } else {
                    newList.add(valueHandler);
                }
            }
        }

        handlerAdapter.setReturnValueHandlers(newList);
    }
}

 

import brave.Tracer;
import com.aicloud.common.core.entity.Result;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

/** * 自定义rest统一结果返回值处理器 */ public class HandlerMethodReturnValueHandlerProxy implements HandlerMethodReturnValueHandler { private HandlerMethodReturnValueHandler proxyObject; private Tracer trace; public HandlerMethodReturnValueHandlerProxy(HandlerMethodReturnValueHandler proxyObject, Tracer trace) { this.proxyObject = proxyObject; this.trace = trace; } /** * 不修改原始的支持类型 */ @Override public boolean supportsReturnType(MethodParameter returnType) { return proxyObject.supportsReturnType(returnType); } /** * 添加 traceId * * @param returnValue 返回值如果为{@linkplain Result}添加 */ @Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception { if (returnValue instanceof Result) { String traceIdString = trace.currentSpan().context().traceIdString(); if (StringUtils.isNotEmpty(traceIdString)) { ((Result) returnValue).setTraceId(traceIdString); } } proxyObject.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } }
#配置文件
spring: zipkin: base
-url: http://localhost:9411/ sender: type: web discoveryClientEnabled: false sleuth: sampler: probability: 1.0

 

3.在logback中添加 traceId信息

 

<!-- [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-} 是traceId配置-->
<property name="encoder_pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS}[%thread] %-5level [%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}] %logger{50} - %msg%n"/>

 

4.zipkin搭建

  参照zipkin 官方地址: https://zipkin.io/pages/quickstart.html

   注:本项目中zipkin的功能只用到了链路的追踪,项目依赖关系分析的部分没有使用

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM