您的位置:首页 > 游戏 > 游戏 > Hystrix 线程池策略时使用ThreadLocal

Hystrix 线程池策略时使用ThreadLocal

2024/10/6 10:42:31 来源:https://blog.csdn.net/u014266077/article/details/140880138  浏览:    关键词:Hystrix 线程池策略时使用ThreadLocal

背景

分页查询单据时,由于单据表数据量很大,单月达到了千万级别,所以,查询先走ES,当ES不可用时,降级走mysql,降级使用了 Hystrix,并且是线程池策略,在实际测试过程中,发现前端提供相同查询参数时,后端会返回不同的响应结果,十分怪异,经排查,组装查询条件时,从上下文里获取了参数,而这些参数是放在 ThreadLocal 里的,ThreadLocal 在不同线程之间的数据隔离是通过每个线程都有一个独立的  ThreadLocal 存储来实现的。然而,Hystrix 使用线程池来实现隔离和限流,这意味着请求可能会在线程池中的不同线程之间切换。这可能导致  ThreadLocal 的数据被意外共享或者丢失。

解决方案

自定义一个 HystrixConcurrencyStrategy,在每次任务执行时正确传递 ThreadLocal 数据。

HystrixConcurrencyStrategy 是 Hystrix 提供的一个扩展点,用于自定义并发执行的行为。通过自定义该策略,可以在 Hystrix 的执行上下文中正确管理 ThreadLocal

public class MyConcurrencyStrategy extends HystrixConcurrencyStrategy {private HystrixConcurrencyStrategy existingConcurrencyStrategy;public MyConcurrencyStrategy(HystrixConcurrencyStrategy existingConcurrencyStrategy) {this.existingConcurrencyStrategy = existingConcurrencyStrategy == null ? HystrixConcurrencyStrategyDefault.getInstance() : existingConcurrencyStrategy;}@Overridepublic <T> Callable<T> wrapCallable(Callable<T> callable) {return new WrappedCallable<>(callable);}private static class WrappedCallable<T> implements Callable<T> {private final Callable<T> actual;private final Map<ThreadLocal<?>, Object> threadLocals;public WrappedCallable(Callable<T> actual) {this.actual = actual;this.threadLocals = captureThreadLocals();}@Overridepublic T call() throws Exception {Map<ThreadLocal<?>, Object> originalThreadLocals = captureThreadLocals();restoreThreadLocals(threadLocals);try {return actual.call();} finally {restoreThreadLocals(originalThreadLocals);}}private Map<ThreadLocal<?>, Object> captureThreadLocals() {Map<ThreadLocal<?>, Object> threadLocals = new HashMap<>();// Capture current ThreadLocal valuesreturn threadLocals;}private void restoreThreadLocals(Map<ThreadLocal<?>, Object> threadLocals) {// Restore ThreadLocal values}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com