Java 中怎么用 Druid 实现分布式链路追踪 TraceId 注入

梦墨姑娘_4698

梦墨姑娘_4698

2026-09-19

872人浏览

原创

Druid 本身不直接支持分布式链路追踪,但可通过集成 SkyWalking、OpenTelemetry 等框架,在 JDBC 执行前经自定义 Filter 将 TraceId 注入 MDC 或 SQL 日志,并配合日志配置实现透传与记录。

java 中怎么用 druid 实现分布式链路追踪 traceid 注入

Druid 本身不直接支持分布式链路追踪(如 TraceId 注入),但它作为数据库连接池,可以通过与主流链路追踪框架(如 SkyWalking、Pinpoint、OpenTelemetry 或 Sleuth+Zipkin)集成,在 SQL 执行阶段透传和记录 TraceId。关键在于:在 JDBC 执行前将当前线程的 TraceId 注入到 Druid 的 Filter 或 Statement 中,并让日志/监控组件能识别它。

1. 确保链路追踪上下文已就绪

TraceId 必须已在当前线程中存在(例如由 Web 层通过 ServletFilter 或 Spring MVC 拦截器注入)。常见方式:

  • 使用 Spring Cloud Sleuth:自动注入 traceId 到 MDC,且提供 Tracer.currentSpan() 获取上下文
  • 使用 OpenTelemetry Java SDK:通过 OpenTelemetry.getGlobalTracer().currentSpan() 获取活跃 Span,再提取 traceId
  • 使用 SkyWalking Agent:无需手动注入,Agent 自动增强 Servlet 和 JDBC,但需确保 Druid 被正确插桩(默认支持)

2. 通过 Druid Filter 注入 TraceId 到 SQL 日志或扩展属性

Druid 提供 Filter 接口,可在 SQL 执行前后插入逻辑。推荐自定义 StatementFilter,将 TraceId 添加到 SQL 日志或 JDBC 扩展字段中:

public class TraceIdFilter extends FilterEventAdapter {
    @Override
    public void dataSource_connectBefore(FilterChain chain, Properties info) {
        // 可选:在连接获取时记录 traceId(如用于连接池监控)
        String traceId = getCurrentTraceId();
        if (traceId != null) {
            info.put("traceId", traceId);
        }
    }
<pre class="brush:php;toolbar:false;">@Override
public void statement_executeBefore(FilterChain chain, PreparedStatement preparedStatement, String sql) {
    String traceId = getCurrentTraceId();
    if (traceId != null) {
        // 方式一:写入 MDC,让 logback/log4j 日志自动携带(推荐)
        MDC.put("traceId", traceId);
        // 方式二:修改 SQL 注释(仅限调试,生产慎用)
        // String tracedSql = "/* traceId=" + traceId + " */ " + sql;
        // chain.statement_execute(preparedStatement, tracedSql);
    }
}

private String getCurrentTraceId() {
    // Sleuth 示例
    CurrentTraceContext currentTraceContext = Tracing.current().currentTraceContext();
    Span currentSpan = currentTraceContext.get();
    return currentSpan != null ? currentSpan.context().traceId() : null;
    // OpenTelemetry 示例:
    // return Span.current().getSpanContext().getTraceId();
}

}

然后在 Spring Boot 中注册该 Filter:

@Bean
public Filter traceIdFilter() {
    return new TraceIdFilter();
}
<p>@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
// ... 其他配置
dataSource.setProxyFilters(Arrays.asList(traceIdFilter()));
return dataSource;
}</p>

3. 配合日志框架输出 TraceId(关键落地环节)

仅注入还不够,必须让数据库操作日志带上 TraceId。以 Logback 为例,在 logback-spring.xml 中配置 pattern:

<pattern>%d{HH:mm:ss.SSS} [%thread] [%X{traceId:-}] %-5level %logger{36} - %msg%n</pattern>

这样 Druid 的慢 SQL 日志、执行日志(开启 druid.stat.logSlowSql=true)就会自动包含 TraceId。

Alibabacloud Sdk Client Initialization For Java
Alibabacloud Sdk Client Initialization For Java

在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。

下载

注意:%X{traceId:-} 表示从 MDC 取值,缺失时显示空字符串;务必在 Filter 中调用 MDC.put("traceId", ...),并在执行后清理(可重写 statement_executeAfter 清理 MDC,避免线程复用污染)。

4. 使用 SkyWalking Agent(零代码侵入方案)

如果你用 SkyWalking,最简单的方式是:不改代码,只加 JVM 参数启动 Agent

-javaagent:/path/to/skywalking-agent.jar
-Dskywalking.agent.service_name=your-service
-Dskywalking.collector.backend_service=your-oap:11800

SkyWalking Agent 已内置对 Druid 1.1.10+ 的支持,会自动:

  • 捕获 SQL 执行耗时、参数、异常
  • 关联上游 HTTP 请求的 TraceId
  • 在 SkyWalking UI 中展示「DB 拓扑」和「Trace 详情」中的 Druid 节点

无需额外 Filter,但需确认 Druid 版本兼容性(建议 ≥ 1.2.16),并启用 druid.stat.mergeSql=true 提升聚合效果。

本质上,Druid 是“被动承载者”,TraceId 注入靠的是上下文传播 + Filter 增强 + 日志/Monitor 集成。选型优先级建议:已有 SkyWalking → 直接用 Agent;已用 Sleuth → 复用 MDC + 自定义 Filter;新项目推荐 OpenTelemetry + 自动 Instrumentation。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

8697

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

5902

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

5312

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

964

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

808

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1136

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2289

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19651

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1055

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习