分布式 日志追踪 链路追踪
日志追踪码传递
MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 和 logback 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的Map,可以往其中添加键值对。
MDC内部使用的是ThreadLocal所以只有本线程才有效
slf4j MDC源码中 没有用 ThreadLocal 就是普通的Map
使用 ThreadLocal 的是其他的日志框架覆盖 MDC实现
比如 logback 就是在自身的包中覆盖了 org.slf4j 包中的部分类
logback 中的MDC 就是使用 ThreadLocal
在 微服务当前切换 服务传递追踪码
gateway 网关传递
直接在转发的请求头中携带即可
Feign Hystrix
网上资料
网上的写法都是介绍 HystrixRequestVariableDefault
feign 如果有用 hystrix 传递时有涉及到跨线程 需要使用 HystrixRequestVariableDefault 传递
或者重写 wrapCallable 方法
1
2
3
4 public <T> Callable<T> wrapCallable(Callable<T> callable) {
//TransmittableThreadLocal修饰原有Callable
return TtlCallable.get(callable);
}还需要按最后 去替换线程池
和 在Configuration配置自定义 HystrixConcurrencyStrategy 替换默认的 HystrixConcurrencyStrategyDefault
1
2
3
4
5
6
7
8
public class HystrixConfig {
public HystrixConcurrencyStrategy requestContextHystrixConcurrencyStrategy() {
return new MyHystrixConcurrencyStrategy();
}
}此处参考了 https://shanhy.blog.csdn.net/article/details/108668952
实测都不太方便
- HystrixRequestVariableDefault 要用 HystrixContextRunnable 或 HystrixContextCallable创建线程才能在线程间传递数据
- wrapCallable 测试无效
HystrixInvocationHandler
阅读源码后发现 wrapCallable 装饰是在 HystrixInvocationHandler.invoke 之前就调用了
invoke 中 还有一个 HystrixCommand 进行回调
等于是 Hystrix 有两层 调用 第一层时参数还有传递 第二层回调时切换线程导致传递的参数丢失
覆盖 HystrixInvocationHandler 类 调用自定义的 HystrixCommand 进行传参
1 | public abstract class Lqs1848HystrixCommand<R> extends HystrixCommand<R>{ |
dubbo 传递
带隐藏参数即可 在RpcContext 中携带
父子线程传递
网上的方法都是
https://yanglinwei.blog.csdn.net/article/details/113503577
https://segmentfault.com/a/1190000020083061
内容都一样也不知道是谁抄谁的
其中最重要的是第一行
package org.slf4j;
要覆盖掉 slf4j 中的MDCAdapter
MDC.mdcAdapter = mdcAdapter;
这个根本就不重要
只要和 logback 一样实现 把 org.slf4j.impl 实现了就行 重写 StaticMDCBinder 即可
1 | public class StaticMDCBinder { |
线程池替换
1 |
|
@Async
1 |
|
MQ传递
我的mq调用都是用的 json格式数据
传输数据时携带上 追踪码即可
总结
跨线程
使用 阿里的 TransmittableThreadLocal
把有提供 回调修饰的方法用 TransmittableThreadLocal提供的工具修饰一下
ThreadLocal<> 替换为 TransmittableThreadLocal<>
再把 所有使用的线程池 换成自己的线程池即可
替换线程池 和 修饰 Callable/Runnable 二者实现其一即可
Hystrix的线程池我就没有替换 而是修饰了 Callable