分布式追踪实战:MyBatis Common Mapper集成SkyWalking全指南
【免费下载链接】Mapper Mybatis Common Mapper - Easy to use 项目地址: https://gitcode.com/gh_mirrors/ma/Mapper
一、痛点与解决方案
在微服务架构中,数据库操作是性能瓶颈和故障排查的关键节点。传统日志打印方式存在三大痛点:
- 链路断裂:无法将SQL执行与上游服务调用关联
- 性能盲区:缺乏SQL执行耗时的精确度量
- 排查困难:无法定位慢查询在分布式链路中的位置
本文将通过MyBatis拦截器(Interceptor)机制,实现与SkyWalking分布式追踪(Distributed Tracing)的无缝集成,构建完整的数据库操作可观测性体系。
二、技术原理与架构设计
2.1 核心组件交互流程
2.2 数据模型设计
SkyWalking追踪数据包含以下核心字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| trace_id | String | 全局唯一追踪ID |
| span_id | String | 局部调用链ID |
| parent_span_id | String | 父调用链ID |
| component | String | 组件名称(MyBatis) |
| operation_name | String | SQL操作描述 |
| peer | String | 数据库连接信息 |
| start_time | long | 开始时间戳 |
| end_time | long | 结束时间戳 |
| tags | Map | 自定义标签(SQL类型/参数) |
三、实现步骤
3.1 环境准备
添加SkyWalking依赖(使用国内Maven仓库):
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<version>9.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>9.7.0</version>
</dependency>
3.2 自定义MyBatis拦截器
package tk.mybatis.mapper.tracing;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.apache.skywalking.apm.toolkit.trace.Tracer;
import org.apache.skywalking.apm.trace.Span;
import org.apache.skywalking.apm.trace.Tags;
import java.util.Properties;
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
org.apache.ibatis.session.RowBounds.class, org.apache.ibatis.session.ResultHandler.class})
})
public class SkyWalkingTracingInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
Object parameter = invocation.getArgs()[1];
// 获取SQL信息
BoundSql boundSql = ms.getBoundSql(parameter);
String sql = boundSql.getSql().trim();
String operation = ms.getSqlCommandType().name() + ":" + ms.getId().substring(ms.getId().lastIndexOf(".") + 1);
// 创建SkyWalking Span
Span span = Tracer.createExitSpan(operation, "jdbc:" + getDatabaseUrl());
Tags.COMPONENT.set(span, "MyBatis");
Tags.DB_TYPE.set(span, "MySQL"); // 根据实际数据库类型调整
Tags.DB_STATEMENT.set(span, sql);
try {
// 执行原方法
return invocation.proceed();
} catch (Exception e) {
Tags.ERROR.set(span, true);
span.log(e.getMessage());
throw e;
} finally {
// 结束Span
span.stop();
}
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// 可配置数据库连接信息等
}
private String getDatabaseUrl() {
// 从配置中获取数据库连接URL
return "mysql://127.0.0.1:3306/mydb";
}
}
3.3 注册拦截器
Spring Boot环境
@Configuration
public class MyBatisConfig {
@Bean
public SkyWalkingTracingInterceptor tracingInterceptor() {
return new SkyWalkingTracingInterceptor();
}
@Bean
public ConfigurationCustomizer configurationCustomizer(SkyWalkingTracingInterceptor interceptor) {
return configuration -> {
configuration.addInterceptor(interceptor);
};
}
}
XML配置环境
<configuration>
<plugins>
<plugin interceptor="tk.mybatis.mapper.tracing.SkyWalkingTracingInterceptor">
<!-- 可配置参数 -->
</plugin>
</plugins>
</configuration>
3.4 配置SkyWalking Agent
下载SkyWalking Agent(国内镜像):
wget https://mirrors.tuna.tsinghua.edu.cn/apache/skywalking/java-agent/9.7.0/apache-skywalking-java-agent-9.7.0.tgz
tar -zxvf apache-skywalking-java-agent-9.7.0.tgz
启动应用时添加JVM参数:
-javaagent:/path/to/skywalking-agent/skywalking-agent.jar
-Dskywalking.agent.service_name=your-service-name
-Dskywalking.collector.backend_service=127.0.0.1:11800
四、高级特性
4.1 SQL参数脱敏
为避免敏感信息泄露,需对SQL参数进行脱敏处理:
private String maskParameters(String sql, Object parameter) {
// 实现参数脱敏逻辑,替换手机号、身份证号等敏感信息
if (parameter instanceof Map) {
Map<?, ?> paramMap = (Map<?, ?>) parameter;
for (Object key : paramMap.keySet()) {
Object value = paramMap.get(key);
if (value instanceof String && isSensitive(key.toString())) {
sql = sql.replace((String) value, "***");
}
}
}
return sql;
}
private boolean isSensitive(String key) {
return key.contains("password") || key.contains("idCard") || key.contains("phone");
}
4.2 慢SQL告警
添加慢查询检测功能:
long startTime = System.currentTimeMillis();
try {
return invocation.proceed();
} finally {
long duration = System.currentTimeMillis() - startTime;
if (duration > 500) { // 500ms阈值
span.tag("slow_sql", "true");
span.tag("duration_ms", String.valueOf(duration));
// 发送告警通知
sendSlowSqlAlert(operation, sql, duration);
}
span.stop();
}
五、集成验证
5.1 验证步骤
-
启动SkyWalking OAP服务器:
# 国内镜像 docker run -d --name skywalking-oap -p 11800:11800 -p 12800:12800 \ --env SW_STORAGE=h2 \ apache/skywalking-oap-server:9.7.0 -
启动SkyWalking UI:
docker run -d --name skywalking-ui -p 8080:8080 \ --link skywalking-oap:oap \ --env SW_OAP_ADDRESS=http://oap:12800 \ apache/skywalking-ui:9.7.0 -
访问UI界面:http://localhost:8080,在"追踪"页面查看SQL执行链路
5.2 预期效果
六、最佳实践与性能优化
6.1 生产环境配置
| 参数 | 推荐值 | 说明 |
|---|---|---|
| 采样率 | 10%~20% | 高流量服务降低采样率 |
| 慢SQL阈值 | 500ms | 根据业务调整 |
| 最大Span数量 | 300/链路 | 防止链路过长 |
6.2 性能优化建议
- 异步上报:使用SkyWalking的异步上报模式减少性能损耗
- 批量处理:批量执行SQL时只创建一个Span
- 缓存策略:缓存MappedStatement元数据减少解析开销
- 采样优化:基于请求特征智能采样(如只采样非GET请求)
6.3 与PageHelper集成
// 在分页插件后执行追踪插件
@Bean
public ConfigurationCustomizer configurationCustomizer(SkyWalkingTracingInterceptor tracingInterceptor,
PageInterceptor pageInterceptor) {
return configuration -> {
configuration.addInterceptor(pageInterceptor);
configuration.addInterceptor(tracingInterceptor);
};
}
七、问题排查与常见错误
7.1 常见异常处理
| 异常 | 原因 | 解决方案 |
|---|---|---|
| ClassNotFoundException | SkyWalking依赖缺失 | 添加apm-toolkit-trace依赖 |
| NoSuchMethodError | MyBatis版本不兼容 | 使用MyBatis 3.5.x以上版本 |
| Span未显示 | 拦截器未注册 | 检查插件注册代码是否生效 |
| 数据乱码 | 编码不一致 | 统一设置UTF-8编码 |
7.2 诊断命令
# 检查SkyWalking Agent是否正确加载
jps -l | grep skywalking
# 查看Agent日志
tail -f /path/to/skywalking-agent/logs/skywalking-api.log
八、总结与展望
本文通过实现自定义MyBatis拦截器,成功将数据库操作纳入SkyWalking分布式追踪体系,解决了传统监控方式的三大痛点。关键成果包括:
- 构建了完整的请求-数据库调用链路追踪
- 实现了SQL性能指标的精确度量
- 提供了慢查询和异常SQL的快速定位能力
未来优化方向:
- 支持SQL参数的安全采集与展示
- 实现数据库连接池状态监控
- 与APM指标分析结合,提供SQL性能趋势预测
通过这套方案,开发团队可以显著提升微服务架构下数据库层的可观测性,快速定位和解决性能瓶颈,保障系统稳定运行。
【免费下载链接】Mapper Mybatis Common Mapper - Easy to use 项目地址: https://gitcode.com/gh_mirrors/ma/Mapper
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



