SDK 形式,利用 threadlocal 实现 trace。http, grpc, rabbitMQ, springcloud-gateway, 异步线程池这类常见场景。
客户端在协议 header 中增加 x-request-id,服务端解析 header 中 x-request-id,存储在 threadlocal,日志框架格式化输出。
java 服务只用依赖 common-tracing.jar lib。
日志格式化输出 traceId 可以使用 MDC,各种协议支持可以考虑 springBoot 的自动注入机制。
grpc
grpc 使用 client 拦截器 和 server拦截器解析 x-request-id。利用 io.grpc.ClientInterceptor,org.lognet.springboot.grpc.GRpcGlobalInterceptor 实现无侵入自动注入。
RabbitMQ
rabbitMQ 使用 messageConvert 解析 x-request-id,使用 SmartInitializingSingleton 获取 SimpleMessageListenerContainer bean,再注入 messagePostProcessors。
代码语言:javascript复制@Slf4j
@Component
@ConditionalOnClass(SimpleMessageListenerContainer.class)
public class FromProcessorConfig implements SmartInitializingSingleton {
@Autowired(required = false)
SimpleMessageListenerContainer listenerContainer;
public void setAfterReceivePostProcessors(SimpleMessageListenerContainer listenerContainer) {
try {
Class<?> obj = Class.forName("org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer");
Field field = obj.getSuperclass().getDeclaredField("afterReceivePostProcessors");
field.setAccessible(true);
Collection<MessagePostProcessor> messagePostProcessors = (Collection<MessagePostProcessor>)field.get(listenerContainer);
if (CollectionUtils.isEmpty(messagePostProcessors)) {
listenerContainer.setAfterReceivePostProcessors(new TracingFromMessagePostProcessor());
}else {
messagePostProcessors.add(new TracingFromMessagePostProcessor());
}
log.info("Initial tracingFromMessagePostProcessor success.");
} catch (Exception e) {
log.error("Initial tracingFromMessagePostProcessor failed.", e);
}
}
@Override
public void afterSingletonsInstantiated() {
if (listenerContainer != null) {
setAfterReceivePostProcessors(listenerContainer);
}
}
}
代码语言:javascript复制@Slf4j
@Component
@ConditionalOnClass(RabbitTemplate.class)
public class ToProcessorConfig implements SmartInitializingSingleton {
@Autowired(required = false)
RabbitTemplate rabbitTemplate;
public void setBeforePublishPostProcessors(RabbitTemplate template) {
try {
Class<?> obj = Class.forName("org.springframework.amqp.rabbit.core.RabbitTemplate");
Field field = obj.getDeclaredField("beforePublishPostProcessors");
field.setAccessible(true);
Collection<MessagePostProcessor> messagePostProcessors = (Collection<MessagePostProcessor>)field.get(template);
if (CollectionUtils.isEmpty(messagePostProcessors)) {
template.setBeforePublishPostProcessors(new TracingToMessagePostProcessor());
}else {
messagePostProcessors.add(new TracingToMessagePostProcessor());
}
log.info("Initial tracingToMessagePostProcessor success.");
} catch (Exception e) {
log.error("Initial tracingToMessagePostProcessor failed.", e);
}
}
@Override
public void afterSingletonsInstantiated() {
if (rabbitTemplate != null) {
setBeforePublishPostProcessors(rabbitTemplate);
}
}
}
http
http 使用 restTemplate 拦截器和 springMVC filter解析
进程内异步线程池
使用 ttl agent 全局替换,集成 MDC。
ttl 作用:将当前线程的 threadLocal,执行线程池任务时,传递到执行线程中。
springcloud - gateway
使用 GlobalFilter 解析 traceId,注意将 GloabalFilter 执行顺序放到最高。
集成功能
- 监控异常请求,告警
- response header 对 traceId 的透出
- 根据参数打印所有链路输入输出参数