分布式链路ID实现

实现原理

api入口或者网关处生成traceId,调用服务时优先检查是否头部带有traceId,有则复用,没有则生成

实现方式

处理api相关traceId

1.通过filter复用或者生成traceId,并且将traceId输入到响应头中

java 复制代码
import java.io.IOException;
import java.util.UUID;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.MDC;
import org.springframework.web.filter.OncePerRequestFilter;

public class TraceIdFilter extends OncePerRequestFilter {
    public TraceIdFilter() {
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String traceId = request.getHeader("X-Trace-Id");
        if (traceId == null) {
            traceId = this.generateTraceId();
        }

        MDC.put("traceId", traceId);
        response.setHeader("X-Trace-Id", traceId);

        try {
            filterChain.doFilter(request, response);
        } finally {
            MDC.clear();
        }

    }

    private String generateTraceId() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}

2、在对应项目中启用filter

java 复制代码
@Configuration
public class WebFilterConfig {

    @Bean
    public FilterRegistrationBean<TraceIdFilter> loggingFilter() {
        FilterRegistrationBean<TraceIdFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new TraceIdFilter());
        registrationBean.addUrlPatterns("/*"); // 只对特定 URL 匹配
        return registrationBean;
    }
}

Feign调用时传递traceId

1、声明拦截器(feign调用时从mdc获取traceId放入请求头中)

java 复制代码
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.MDC;

public class FeIgnMCDInterceptor implements RequestInterceptor {
    public FeIgnMCDInterceptor() {
    }

    public void apply(RequestTemplate template) {
        String traceId = MDC.get("traceId");
        if (traceId != null) {
            template.header("X-Trace-Id", new String[]{traceId});
        }

    }
}

2、启用拦截器

java 复制代码
// 任意位置注册为springbean即可
@Bean
public FeIgnMCDInterceptor feIgnMCDInterceptor() {
    return new FeIgnMCDInterceptor();
}

日志配置文件中打印traceId

XML 复制代码
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [${application_name}] [%X{traceId}] [%thread] %-5level %logger - [%method,%line] - %msg%n" />
相关推荐
秋天的怀念_David10 分钟前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas10023 分钟前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin1 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质1 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3762 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你02142 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
步行cgn3 小时前
Spring MVC + Thymeleaf 模板解析失败:从 500 错误到页面正常显示
java·spring·mvc
lgcgkCQ3 小时前
【AI 转型实战 1】SpringAI 入门:搭建基础大模型对话能力
java·ai·agent·rag·spring ai·mcp·langchain4j
Wang's Blog4 小时前
Java 项目实战:交友项目 - 用户体系集成总结
java·开发语言·交友
学到老活到老4 小时前
第 24 集:配置文件写了 80,Spring Boot 为什么读到 90?
java·后端·spring