上一篇說了關于MDC跨執行緒為null的理解,而本講主要說一下,如何去解決它,事實上,Hystrix為我們留了這個口,我們只需要繼承HystrixConcurrencyStrategy,然后重寫wrapCallable方法,再把這個重寫的物件注冊到Hystrix里就可以了,跨執行緒共享資料,可以使用阿里的 transmittable-thread-local組件,如果只是共離MDC的話,可以自己寫個組件就行,
一 ThreadMdcUtil用來同步MDC物件
public class ThreadMdcUtil {
public static <T> Callable<T> wrap(final Callable<T> callable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
}
else {
MDC.setContextMap(context);
}
try {
return callable.call();
}
finally {
MDC.clear();
}
};
}
public static Runnable wrap(final Runnable runnable, final Map<String, String> context) {
return () -> {
if (context == null) {
MDC.clear();
}
else {
MDC.setContextMap(context);
}
try {
runnable.run();
}
finally {
MDC.clear();
}
};
}
}
重寫HystrixConcurrencyStrategy,將主執行緒的MDC傳入Hystrix建立的新執行緒
/**
* 執行緒背景關系傳遞,hystrix的相關實作有興趣可以看原始碼, hystrix提供了這個口子可以處理執行緒間傳值問題,這里不做過多贅述
*/
public class RequestContextHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {
@Override
public <T> Callable<T> wrapCallable(final Callable<T> callable) {
// 使用阿里的 TtlCallable 重新包一層,解決執行緒間資料傳遞問題
// return TtlCallable.get(callable);
// 使用自定義的包裝物件,將當前mdc復制到Hystrix新執行緒中
return ThreadMdcUtil.wrap(callable, MDC.getCopyOfContextMap());
}
}
注冊我們的RequestContextHystrixConcurrencyStrategy策略到Hystrix
@Configuration
@Slf4j
public class HystrixCircuitBreakerConfiguration {
@PostConstruct
public void init() {
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new RequestContextHystrixConcurrencyStrategy());
}
}
運行結果,使用openFeign時,已經共享了traceId這個資料值

作者:倉儲大叔,張占嶺,
榮譽:微軟MVP
QQ:853066980
支付寶掃一掃,為大叔打賞!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/542578.html
標籤:其他
上一篇:聊聊GC是如何快速列舉根節點的
下一篇:FPGA用ROM輸出正弦波
