日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HYSTRIX实现主线程和子线程的THREADLOCAL上下文传递

發布時間:2024/10/5 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HYSTRIX实现主线程和子线程的THREADLOCAL上下文传递 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題描述

我在使用日志鏈路追蹤的時候(基于SLF4J MDC機制實現日志的鏈路追蹤),我發現使用Hystrix線程池隔離的時候,我不能將子線程沒有復制主線程的MDC上下文(Slf4j MDC機制
),導致日志鏈路斷掉。

問題分析

Hystrix的線程池隔離是使用HystrixThreadPool來實現的。而獲取HystrixThreadPool是在HystrixConcurrencyStrategy。在這里我們可以看到類的描述:

Abstract class for defining different behavior or implementations for concurrency related aspects of the system with default implementations.
For example, every Callable executed by HystrixCommand will call wrapCallable(Callable) to give a chance for custom implementations to decorate the Callable with additional behavior.
When you implement a concrete HystrixConcurrencyStrategy, you should make the strategy idempotent w.r.t ThreadLocals. Since the usage of threads by Hystrix is internal, Hystrix does not attempt to apply the strategy in an idempotent way. Instead, you should write your strategy to work idempotently. See Timeout handling fails for non-idempotent strategy · Issue #351 · Netflix/Hystrix · GitHub for a more detailed discussion.
See HystrixPlugins or the Hystrix GitHub Wiki for information on configuring plugins: Plugins · Netflix/Hystrix Wiki · GitHub.

大致意思是HystrixConcurrencyStrategy提供了一套默認的并發策略實現。我們可以根據我們自己不同需求通過裝飾去擴展它。如每次執行HystrixCommand的時候都會去調用wrapCallable(Callable) 方法,這里我們就可以通過裝飾Callable使它提供一些額外的功能(如ThreadLocal上下文傳遞)。還附上了插件的文檔:Plugins · Netflix/Hystrix Wiki · GitHub。

打開文檔,將會教我們如何去擴展HystrixConcurrencyStrategy并使它生效。

實現

擴展HystrixConcurrencyStrategy

/*** Hystrix線程池隔離支持日志鏈路跟蹤** @author yuhao.wang3*/ public class MdcHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {@Overridepublic <T> Callable<T> wrapCallable(Callable<T> callable) {return new MdcAwareCallable(callable, MDC.getCopyOfContextMap());}private class MdcAwareCallable<T> implements Callable<T> {private final Callable<T> delegate;private final Map<String, String> contextMap;//具體怎么定義這個方法,你可以啟動在這里打斷點,看看你的線程中有些什么必須要有的東西public MdcAwareCallable(Callable<T> callable, Map<String, String> contextMap) {this.delegate = callable;this.contextMap = contextMap != null ? contextMap : new HashMap();}@Overridepublic T call() throws Exception {try {MDC.setContextMap(contextMap);return delegate.call();} finally {MDC.clear();}}} }

通過裝飾Callable類,我們在MdcAwareCallable#call()方法中先將MDC上下文復制到子線程。

注冊插件

@Configuration public class HystrixConfig {//用來攔截處理HystrixCommand注解@Beanpublic HystrixCommandAspect hystrixAspect() {return new HystrixCommandAspect();}@PostConstructpublic void init() {HystrixPlugins.getInstance().registerConcurrencyStrategy(new MdcHystrixConcurrencyStrategy());}}

參考: https://github.com/Netflix/Hystrix/wiki/Plugins#concurrencystrategy

源碼

https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

總結

以上是生活随笔為你收集整理的HYSTRIX实现主线程和子线程的THREADLOCAL上下文传递的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。