Hystrix上下文传递
一、背景
开发中使用 ThreadLocal 来存放日志追踪码和分表等信息,但由于 Hystrix 使用了线程池 导致了 ThreadLocal 数据丢失。
二、尝试解决
TTL
TransmittableThreadLocal
HystrixRequestContext
忘了啥问题了 好像是存储时会出错 如果要使用得替换很多东西
HystrixConcurrencyStrategy&HystrixCommandExecutionHook
1 | HystrixPlugins.getInstance().registerConcurrencyStrategy(new RequestContextHystrixConcurrencyStrategy()); |
包名类名覆盖
实现一个 HystrixCommand
覆盖 feign.hystrix.HystrixInvocationHandler 使用自己实现的 HystrixCommand 进行回调
本地测试通过线上失败
原因是 Hystrix 上下文传递的逻辑 我提取到一个单独的Maven项目中
发布到线上变成 jar包时 所有引用 第三方jar和自己的公用 jar 处于 项目中的 lib 目录
lib 目录中的加载时 由于依赖 Hystrix 官方包 先加载了 官方包 重复加载的class会被忽略,只有第一个生效
导致线上始终无法生效
本地 自己的公用包 应该是加载到 class 目录下
class目录优先级更高 所以覆盖成功
Java的包名覆盖机制受太多外部条件影响 最终还是放弃了
- 同一个ClassLoader实例加载的类不能重复(不同的class文件,同样的类名也是重复),如果强行用同一个ClassLoader实例加载同一个类,则会报错
attempted duplicate class definition for {your class}
java -classpath(-cp)
加载配置jar包(classes)时,会按照书写定义顺序加载class,之后重复加载的class会被忽略,只有第一个生效- Idea中可以通过在Project Settings -> Modules -> Dependencies中通过上下箭头调整jar加载顺序,其实也就是调整
-classpath(-cp)
后的jar包书写顺序- Tomcat下的jar包貌似不同版本加载策略不同
- spring-boot是自定义的jar包加载策略,顺序未确认,猜测默认是按字母排序
5.SPI
扩展 HystrixConcurrencyStrategy 后不用 registerConcurrencyStrategy 注册
而是在工程的classpath下引入hystrix-plugins.properties配置文件
1 | com.xx.xx.xx.xxxStrategy = |
三、总结
前后用了N种方式 最终还是用 SPI 的方式实现了想要的效果…
具体实现参照之前的 日志链路追踪