一、traceid 是什么?
- traceid 就是给每一条请求链路分配的全局唯一 “身份证号” —— 不管是单体项目里的一次接口请求,还是分布式微服务里跨多个服务的调用流程,只要属于同一条请求链路,全程共用同一个 traceid。
- 你可以把它理解成:用户在 app 点了 “下单” 按钮,这个请求从前端→网关→订单服务→用户服务→支付服务,整个流程会被分配一个唯一的 traceid,所有环节的日志、调用记录都带上这个 id。排查问题时,只要搜这个 traceid,就能把整条链路的日志 / 调用记录都揪出来,不用在海量日志里大海捞针。
场景一:无skywalking的最优实现
核心方案
mdc(日志上下文) + filter(入口生成/读取traceid) + taskdecorator(异步线程传递) + feign/resttemplate拦截器(微服务跨服务传递)
适用场景
- 中小型单体/微服务项目;
- 无可视化链路分析需求,仅需日志携带traceid定位问题;
- 不愿引入额外中间件(skywalking oap)增加运维成本。
1. 依赖配置(拆分springboot/springcloud)
1.1 springboot单体项目依赖
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.7.15</version> <!-- 3.x可替换为3.2.0 -->
<relativepath/>
</parent>
<groupid>com.example</groupid>
<artifactid>boot-traceid-no-skywalking</artifactid>
<version>0.0.1-snapshot</version>
<dependencies>
<!-- springboot web核心 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<!-- 工具类:判空/字符串处理 -->
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-lang3</artifactid>
<version>3.14.0</version>
</dependency>
<!-- 可选:hutool(雪花id生成) -->
<dependency>
<groupid>cn.hutool</groupid>
<artifactid>hutool-all</artifactid>
<version>5.8.22</version>
</dependency>
<!-- 测试依赖(非核心) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<version>2.7.15</version>
</plugin>
</plugins>
</build>
</project>1.2 springcloud微服务项目依赖
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.7.15</version> <!-- 对应cloud 2021.0.x -->
<relativepath/>
</parent>
<groupid>com.example</groupid>
<artifactid>cloud-traceid-no-skywalking</artifactid>
<version>0.0.1-snapshot</version>
<dependencies>
<!-- 基础依赖(同springboot) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-lang3</artifactid>
<version>3.14.0</version>
</dependency>
<dependency>
<groupid>cn.hutool</groupid>
<artifactid>hutool-all</artifactid>
<version>5.8.22</version>
</dependency>
<!-- 微服务核心:openfeign -->
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>
<!-- cloud版本管理 -->
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-dependencies</artifactid>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencymanagement>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<version>2.7.15</version>
</plugin>
</plugins>
</build>
</project>2. 核心代码实现(无skywalking专属)
2.1 traceid工具类(自定义生成/传递)
package com.example.traceid.util;
import cn.hutool.core.lang.snowflake;
import cn.hutool.core.net.netutil;
import cn.hutool.core.util.idutil;
import org.apache.commons.lang3.stringutils;
import org.slf4j.mdc;
import java.util.uuid;
/**
* 无skywalking时:自定义traceid生成/管理工具类
*/
public class traceidutils {
// mdc中traceid的key(日志配置用%x{traceid}读取)
public static final string trace_id_mdc_key = "traceid";
// http头传递traceid的key
public static final string trace_id_header_key = "x-trace-id";
// 雪花id生成器(高并发用,单机/低并发可只用uuid)
private static final snowflake snowflake = idutil.createsnowflake(
netutil.ipv4tolong(netutil.getlocalhoststr()) % 32, 1l
);
/**
* 生成traceid:低并发用uuid,高并发用雪花id
*/
public static string generatetraceid() {
// 方案1:uuid(默认,无需额外依赖)
return uuid.randomuuid().tostring().replace("-", "");
// 方案2:雪花id(高并发切换)
// return snowflake.nextidstr();
}
/**
* 从mdc获取traceid,兜底返回unknown
*/
public static string gettraceid() {
string traceid = mdc.get(trace_id_mdc_key);
return stringutils.isblank(traceid) ? "unknown" : traceid;
}
/**
* 手动设置traceid到mdc
*/
public static void settraceidtomdc(string traceid) {
if (stringutils.isnotblank(traceid)) {
mdc.put(trace_id_mdc_key, traceid);
}
}
/**
* 清除mdc中的traceid
*/
public static void cleartraceidfrommdc() {
mdc.remove(trace_id_mdc_key);
}
}2.2 traceid过滤器(请求入口生成/读取traceid)
package com.example.traceid.filter;
import com.example.traceid.util.traceidutils;
import org.apache.commons.lang3.stringutils;
import org.slf4j.mdc;
import org.springframework.core.ordered;
import org.springframework.core.annotation.order;
import org.springframework.stereotype.component;
import javax.servlet.*;
import javax.servlet.http.httpservletrequest;
import java.io.ioexception;
/**
* 无skywalking时:请求入口生成/读取traceid,放入mdc
* 优先级最高,保证所有逻辑执行前已有traceid
*/
@component
@order(ordered.highest_precedence)
public class traceidmdcfilter implements filter {
@override
public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {
try {
httpservletrequest httprequest = (httpservletrequest) request;
// 1. 优先读取上游传递的traceid(网关/其他服务)
string traceid = httprequest.getheader(traceidutils.trace_id_header_key);
// 2. 上游无则生成新的
if (stringutils.isblank(traceid)) {
traceid = traceidutils.generatetraceid();
}
// 3. 放入mdc,供日志读取
mdc.put(traceidutils.trace_id_mdc_key, traceid);
// 4. 执行后续逻辑
chain.dofilter(request, response);
} finally {
// 核心:请求结束清除mdc,避免线程池复用导致traceid错乱
mdc.clear();
}
}
}2.3 异步线程池配置(解决异步traceid丢失)
package com.example.traceid.config;
import org.slf4j.mdc;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.core.task.taskdecorator;
import org.springframework.scheduling.annotation.enableasync;
import org.springframework.scheduling.concurrent.threadpooltaskexecutor;
import java.util.map;
import java.util.concurrent.executor;
import java.util.concurrent.threadpoolexecutor;
/**
* 无skywalking时:异步线程池配置,传递mdc上下文
*/
@configuration
@enableasync
public class asynctraceconfig {
// 自定义taskdecorator:复制父线程mdc到子线程
private static class mdctracedecorator implements taskdecorator {
@override
public runnable decorate(runnable runnable) {
map<string, string> parentmdc = mdc.getcopyofcontextmap();
return () -> {
try {
if (parentmdc != null) {
mdc.setcontextmap(parentmdc);
}
runnable.run();
} finally {
mdc.clear(); // 子线程执行完清除mdc
}
};
}
}
// 全局异步线程池
@bean("asynctraceexecutor")
public executor asynctraceexecutor() {
threadpooltaskexecutor executor = new threadpooltaskexecutor();
int core = runtime.getruntime().availableprocessors() * 2;
executor.setcorepoolsize(core);
executor.setmaxpoolsize(core * 2);
executor.setqueuecapacity(200);
executor.setthreadnameprefix("async-trace-");
executor.settaskdecorator(new mdctracedecorator()); // 绑定装饰器
executor.setrejectedexecutionhandler(new threadpoolexecutor.callerrunspolicy());
executor.setwaitfortaskstocompleteonshutdown(true);
executor.setawaitterminationseconds(30);
executor.initialize();
return executor;
}
}2.4 微服务跨服务传递(feign/resttemplate拦截器)
2.4.1 feign拦截器(微服务专属)
package com.example.traceid.interceptor;
import com.example.traceid.util.traceidutils;
import feign.requestinterceptor;
import feign.requesttemplate;
import org.springframework.stereotype.component;
/**
* 无skywalking时:feign调用传递traceid
*/
@component
public class feigntraceinterceptor implements requestinterceptor {
@override
public void apply(requesttemplate template) {
string traceid = traceidutils.gettraceid();
if (!"unknown".equals(traceid)) {
template.header(traceidutils.trace_id_header_key, traceid);
}
}
}2.4.2 resttemplate拦截器(微服务专属)
package com.example.traceid.config;
import com.example.traceid.util.traceidutils;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.http.client.clienthttprequestinterceptor;
import org.springframework.web.client.resttemplate;
import java.util.collections;
/**
* 无skywalking时:resttemplate传递traceid
*/
@configuration
public class resttemplatetraceconfig {
@bean
public resttemplate resttemplate() {
resttemplate resttemplate = new resttemplate();
resttemplate.setinterceptors(collections.singletonlist((request, body, execution) -> {
string traceid = traceidutils.gettraceid();
if (!"unknown".equals(traceid)) {
request.getheaders().add(traceidutils.trace_id_header_key, traceid);
}
return execution.execute(request, body);
}));
return resttemplate;
}
}2.5 日志配置(logback-spring.xml)
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanperiod="30 seconds">
<contextname>traceid-no-skywalking</contextname>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.consoleappender">
<encoder>
<charset>utf-8</charset>
<!-- 核心:%x{traceid}读取mdc中的traceid -->
<pattern>%d{yyyy-mm-dd hh:mm:ss.sss} [%thread] [%x{traceid}] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 文件输出 -->
<appender name="file" class="ch.qos.logback.core.rolling.rollingfileappender">
<file>logs/app.log</file>
<rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy">
<filenamepattern>logs/app.%d{yyyy-mm-dd}.log</filenamepattern>
<maxhistory>7</maxhistory>
<maxfilesize>100mb</maxfilesize>
</rollingpolicy>
<encoder>
<charset>utf-8</charset>
<pattern>%d{yyyy-mm-dd hh:mm:ss.sss} [%thread] [%x{traceid}] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>3. 无skywalking的核心验证
- 同步接口:日志中
[%x{traceid}]显示自定义生成的traceid; - 异步任务:子线程日志traceid与父线程一致;
- 微服务调用:下游服务日志traceid与上游一致;
- 无任何额外中间件依赖,仅依赖spring原生能力。
场景二:有skywalking的最优实现
核心方案
复用skywalking traceid + mdc绑定 + 上下文传递(异步/跨服务)
核心差异
- 无需自定义生成traceid,直接复用skywalking的全局traceid;
- 日志中同时绑定skywalking traceid,实现「日志traceid=链路traceid」;
- 异步/跨服务场景需传递skywalking上下文,保证链路不中断。
1. 依赖配置(拆分springboot/springcloud)
1.1 springboot单体项目(新增skywalking依赖)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.7.15</version>
<relativepath/>
</parent>
<groupid>com.example</groupid>
<artifactid>boot-traceid-with-skywalking</artifactid>
<version>0.0.1-snapshot</version>
<dependencies>
<!-- 基础依赖(同无skywalking) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-lang3</artifactid>
<version>3.14.0</version>
</dependency>
<!-- skywalking核心依赖 -->
<dependency>
<groupid>org.apache.skywalking</groupid>
<artifactid>apm-toolkit-spring-boot-starter</artifactid>
<version>8.16.0</version> <!-- 与skywalking oap版本一致 -->
</dependency>
<!-- skywalking日志增强:自动绑定traceid到mdc -->
<dependency>
<groupid>org.apache.skywalking</groupid>
<artifactid>apm-toolkit-logback-1.x</artifactid>
<version>8.16.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<version>2.7.15</version>
</plugin>
</plugins>
</build>
</project>1.2 springcloud微服务项目(新增skywalking依赖)
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/pom/4.0.0"
xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"
xsi:schemalocation="http://maven.apache.org/pom/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0</modelversion>
<parent>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.7.15</version>
<relativepath/>
</parent>
<groupid>com.example</groupid>
<artifactid>cloud-traceid-with-skywalking</artifactid>
<version>0.0.1-snapshot</version>
<dependencies>
<!-- 基础依赖(同无skywalking) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-web</artifactid>
</dependency>
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-lang3</artifactid>
<version>3.14.0</version>
</dependency>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-starter-openfeign</artifactid>
</dependency>
<!-- skywalking核心依赖 -->
<dependency>
<groupid>org.apache.skywalking</groupid>
<artifactid>apm-toolkit-spring-boot-starter</artifactid>
<version>8.16.0</version>
</dependency>
<!-- skywalking feign增强:跨服务链路追踪 -->
<dependency>
<groupid>org.apache.skywalking</groupid>
<artifactid>apm-toolkit-feign</artifactid>
<version>8.16.0</version>
</dependency>
<!-- skywalking日志增强 -->
<dependency>
<groupid>org.apache.skywalking</groupid>
<artifactid>apm-toolkit-logback-1.x</artifactid>
<version>8.16.0</version>
</dependency>
</dependencies>
<dependencymanagement>
<dependencies>
<dependency>
<groupid>org.springframework.cloud</groupid>
<artifactid>spring-cloud-dependencies</artifactid>
<version>2021.0.5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencymanagement>
<build>
<plugins>
<plugin>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-maven-plugin</artifactid>
<version>2.7.15</version>
</plugin>
</plugins>
</build>
</project>2. skywalking极简部署(docker,中小型项目首选)
# 1. 拉取oap和ui镜像(版本与项目依赖一致) docker pull apache/skywalking-oap-server:8.16.0 docker pull apache/skywalking-ui:8.16.0 # 2. 启动oap(单节点,h2存储,无需额外数据库) docker run -d \ --name skywalking-oap \ -p 11800:11800 \ # agent上报端口 -p 12800:12800 \ # ui访问oap端口 -e sw_storage=h2 \ apache/skywalking-oap-server:8.16.0 # 3. 启动ui(可视化界面,访问http://localhost:8080) docker run -d \ --name skywalking-ui \ -p 8080:8080 \ --link skywalking-oap:oap \ -e sw_oap_address=http://oap:12800 \ apache/skywalking-ui:8.16.0
3. 核心代码实现(有skywalking专属)
3.1 traceid工具类(复用skywalking traceid)
package com.example.traceid.util;
import org.apache.commons.lang3.stringutils;
import org.apache.skywalking.apm.toolkit.trace.tracecontext;
import org.slf4j.mdc;
/**
* 有skywalking时:复用其traceid,无需自定义生成
*/
public class traceidutils {
// 复用skywalking的mdc key(sw_trace_id),也可自定义
public static final string trace_id_mdc_key = "sw_trace_id";
public static final string trace_id_header_key = "x-trace-id";
/**
* 获取traceid:优先skywalking,兜底unknown
*/
public static string gettraceid() {
// skywalking原生traceid
string skywalkingtraceid = tracecontext.traceid();
if (stringutils.isnotblank(skywalkingtraceid) && !"n/a".equals(skywalkingtraceid)) {
return skywalkingtraceid;
}
// 兜底读取mdc
string mdctraceid = mdc.get(trace_id_mdc_key);
return stringutils.isblank(mdctraceid) ? "unknown" : mdctraceid;
}
/**
* 绑定skywalking traceid到mdc(仅特殊场景用)
*/
public static void bindskywalkingtraceidtomdc() {
string traceid = tracecontext.traceid();
if (stringutils.isnotblank(traceid) && !"n/a".equals(traceid)) {
mdc.put(trace_id_mdc_key, traceid);
}
}
}3.2 traceid过滤器(简化:仅绑定skywalking traceid到mdc)
package com.example.traceid.filter;
import com.example.traceid.util.traceidutils;
import org.apache.skywalking.apm.toolkit.trace.tracecontext;
import org.slf4j.mdc;
import org.springframework.core.ordered;
import org.springframework.core.annotation.order;
import org.springframework.stereotype.component;
import javax.servlet.*;
import java.io.ioexception;
/**
* 有skywalking时:过滤器仅绑定其traceid到mdc,无需生成
*/
@component
@order(ordered.highest_precedence)
public class traceidmdcfilter implements filter {
@override
public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception {
try {
// 绑定skywalking traceid到mdc,供日志读取
traceidutils.bindskywalkingtraceidtomdc();
chain.dofilter(request, response);
} finally {
mdc.clear();
// 释放skywalking上下文(避免内存泄漏)
tracecontext.release();
}
}
}3.3 异步线程池配置(传递skywalking上下文)
package com.example.traceid.config;
import org.apache.skywalking.apm.toolkit.trace.tracecontext;
import org.slf4j.mdc;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.core.task.taskdecorator;
import org.springframework.scheduling.annotation.enableasync;
import org.springframework.scheduling.concurrent.threadpooltaskexecutor;
import java.util.map;
import java.util.concurrent.executor;
import java.util.concurrent.threadpoolexecutor;
/**
* 有skywalking时:异步线程池传递mdc+skywalking上下文
*/
@configuration
@enableasync
public class asynctraceconfig {
private static class mdctracedecorator implements taskdecorator {
@override
public runnable decorate(runnable runnable) {
// 复制父线程mdc和skywalking traceid
map<string, string> parentmdc = mdc.getcopyofcontextmap();
string parentskywalkingtraceid = tracecontext.traceid();
return () -> {
try {
// 子线程绑定mdc
if (parentmdc != null) {
mdc.setcontextmap(parentmdc);
}
// 子线程绑定skywalking traceid(核心:保证链路不中断)
if (stringutils.isnotblank(parentskywalkingtraceid) && !"n/a".equals(parentskywalkingtraceid)) {
tracecontext.continuetrace(parentskywalkingtraceid);
}
runnable.run();
} finally {
mdc.clear();
tracecontext.release(); // 释放skywalking上下文
}
};
}
}
@bean("asynctraceexecutor")
public executor asynctraceexecutor() {
threadpooltaskexecutor executor = new threadpooltaskexecutor();
int core = runtime.getruntime().availableprocessors() * 2;
executor.setcorepoolsize(core);
executor.setmaxpoolsize(core * 2);
executor.setqueuecapacity(200);
executor.setthreadnameprefix("async-trace-");
executor.settaskdecorator(new mdctracedecorator());
executor.setrejectedexecutionhandler(new threadpoolexecutor.callerrunspolicy());
executor.initialize();
return executor;
}
}3.4 日志配置(绑定skywalking traceid)
<?xml version="1.0" encoding="utf-8"?>
<configuration scan="true" scanperiod="30 seconds">
<!-- 引入skywalking默认配置 -->
<include resource="org/apache/skywalking/apm/toolkit/log/logback/default.xml"/>
<contextname>traceid-with-skywalking</contextname>
<appender name="console" class="ch.qos.logback.core.consoleappender">
<encoder>
<charset>utf-8</charset>
<!-- %x{sw_trace_id}:skywalking原生traceid -->
<pattern>%d{yyyy-mm-dd hh:mm:ss.sss} [%thread] [%x{sw_trace_id}] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.rollingfileappender">
<file>logs/app.log</file>
<rollingpolicy class="ch.qos.logback.core.rolling.timebasedrollingpolicy">
<filenamepattern>logs/app.%d{yyyy-mm-dd}.log</filenamepattern>
<maxhistory>7</maxhistory>
<maxfilesize>100mb</maxfilesize>
</rollingpolicy>
<encoder>
<charset>utf-8</charset>
<pattern>%d{yyyy-mm-dd hh:mm:ss.sss} [%thread] [%x{sw_trace_id}] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>3.5 项目挂载skywalking agent(核心步骤)
启动项目时添加jvm参数(本地/生产通用):
# 本地idea vm options -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -dsw_agent_name=boot-traceid-demo # 服务名(ui中显示) -dsw_agent_collector_backend_services=127.0.0.1:11800 # oap地址 # 生产jar启动 java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \ -dsw_agent_name=cloud-traceid-demo \ -dsw_agent_collector_backend_services=192.168.1.100:11800 \ -jar app.jar
4. 有skywalking的核心验证
- 日志中
[%x{sw_trace_id}]显示skywalking的全局traceid; - 异步任务:子线程traceid与父线程一致,skywalking ui可看到异步链路;
- 微服务调用:上下游traceid一致,skywalking ui可看到跨服务完整链路;
- 访问skywalking ui(http://localhost:8080),可通过traceid搜索整条链路。
核心差异总结
| 维度 | 无skywalking(纯自研) | 有skywalking(复用traceid) |
|---|---|---|
| traceid生成 | 自定义(uuid/雪花id) | 复用skywalking全局traceid(无需自定义) |
| 核心目标 | 日志携带traceid,定位问题 | 日志+可视化链路统一,支持跨服务/异步链路分析 |
| 运维成本 | 0(仅代码) | 低(单节点docker部署oap+ui) |
| 异步/跨服务处理 | 仅传递mdc上下文 | 传递mdc+skywalking上下文(保证链路不中断) |
| 日志配置 | 读取自定义mdc key(traceid) | 读取skywalking mdc key(sw_trace_id) |
到此这篇关于springboot集成traceid的方案详解(追踪id)的文章就介绍到这了,更多相关springboot集成traceid内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论