Apache ShenYu集成分布式追踪:Jaeger部署与配置
分布式系统中,请求链路追踪是排查问题、优化性能的关键能力。Apache ShenYu作为Java原生API网关,支持通过插件机制集成分布式追踪系统。本文将详细介绍如何在ShenYu网关中部署和配置Jaeger,实现全链路追踪。
系统架构与追踪原理
Apache ShenYu网关通过插件化设计支持各类扩展功能,追踪能力可通过自定义插件实现。系统默认提供监控插件MonitorPlugin,记录请求计数、响应时间等基础指标,但未直接实现分布式追踪。
Jaeger作为CNCF毕业项目,采用OpenTracing规范,通过以下组件实现分布式追踪:
- Jaeger Client:埋点API与应用集成
- Agent:本地转发器,收集Trace数据
- Collector:处理并存储追踪数据
- Query:UI查询界面
环境准备与部署
1. Jaeger服务部署
使用Docker快速启动Jaeger服务:
docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.55
访问http://localhost:16686可打开Jaeger UI界面。
2. 项目依赖配置
在网关项目pom.xml中添加Jaeger客户端依赖:
<dependency>
<groupId>io.opentracing.contrib</groupId>
<artifactId>opentracing-spring-web-starter</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-client</artifactId>
<version>1.55.0</version>
</dependency>
追踪插件开发
1. 自定义追踪插件
创建TracingPlugin类继承AbstractSoulPlugin:
package org.dromara.soul.web.plugin.tracing;
import io.opentracing.Tracer;
import org.dromara.soul.web.plugin.AbstractSoulPlugin;
import org.dromara.soul.web.plugin.SoulPluginChain;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public class TracingPlugin extends AbstractSoulPlugin {
private final Tracer tracer;
public TracingPlugin(Tracer tracer) {
this.tracer = tracer;
}
@Override
public String named() {
return "tracing";
}
@Override
public int getOrder() {
return 100; // 确保在路由插件前执行
}
@Override
public Mono<Void> execute(ServerWebExchange exchange, SoulPluginChain chain) {
// 创建Span并设置Tags
return chain.execute(exchange)
.doOnSuccess(v -> finishSpan(exchange))
.doOnError(e -> handleError(exchange, e));
}
// 实现Span创建、上下文传递、错误处理等逻辑
}
2. 插件配置类
创建配置类注册Tracer和自定义插件:
@Configuration
public class TracingConfig {
@Bean
public Tracer jaegerTracer() {
return JaegerTracerBuilder
.forService("shenyu-gateway")
.withSampler(SamplerConfiguration.fromEnv().withType("const").withParam(1))
.withReporter(ReporterConfiguration.fromEnv().withLogSpans(true))
.build();
}
@Bean
public TracingPlugin tracingPlugin(Tracer tracer) {
return new TracingPlugin(tracer);
}
}
网关配置与集成
1. 启用插件
在Zookeeper配置中心启用自定义追踪插件,通过PluginController添加插件配置:
{
"id": "tracing",
"name": "tracing",
"enabled": true,
"config": "{\"host\":\"localhost\",\"port\":5775}"
}
2. 调整监控插件
修改MonitorPlugin,添加追踪上下文关联:
private MonitorDO buildMonitorData(final ServerWebExchange exchange) {
// 从请求上下文中获取TraceID
String traceId = exchange.getAttribute("X-B3-TraceId");
MonitorDO monitorDO = new MonitorDO();
monitorDO.setTraceId(traceId); // 添加TraceID字段
// 其他监控字段设置
return monitorDO;
}
验证与可视化
1. 发起测试请求
通过网关调用后端服务:
curl http://localhost:9195/http/order/findById?id=1
2. 在Jaeger UI查看追踪
访问Jaeger UI(http://localhost:16686),选择服务shenyu-gateway,可查看完整调用链路:
- 网关入口Span
- 路由选择过程
- 后端服务调用
- 响应处理流程
高级配置与优化
1. 采样率调整
生产环境建议调整采样率减少性能开销:
.withSampler(SamplerConfiguration.fromEnv()
.withType("probabilistic")
.withParam(0.01)) // 1%采样率
2. 异步处理优化
参考MonitorPlugin的线程池设计,优化追踪数据上报:
executor = new ThreadPoolExecutor(MAX_THREAD, MAX_THREAD, 0, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(),
SoulThreadFactory.create("tracing-thread", false));
常见问题排查
- Trace不连贯:检查B3协议头是否正确传递,确保上下游服务都使用Jaeger客户端
- 性能问题:通过InfluxDbService监控追踪插件带来的性能开销
- 数据丢失:调整Reporter配置,增加队列大小和重试机制
总结
通过集成Jaeger分布式追踪,Apache ShenYu网关实现了全链路可视化能力,结合现有监控插件MonitorPlugin,可构建完整的可观测性平台。生产环境中建议根据流量规模调整采样策略,并通过RuleController配置精细化的追踪规则。
完整实现可参考官方文档和示例项目,更多高级特性如 baggage 传递、自定义标签等可参考Jaeger官方文档进一步扩展。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




