Hystrix 线程池策略时使用ThreadLocal
创始人
2024-11-13 05:08:59

背景

分页查询单据时,由于单据表数据量很大,单月达到了千万级别,所以,查询先走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;     }      @Override     public  Callable wrapCallable(Callable callable) {         return new WrappedCallable<>(callable);     }      private static class WrappedCallable implements Callable {         private final Callable actual;         private final Map, Object> threadLocals;          public WrappedCallable(Callable actual) {             this.actual = actual;             this.threadLocals = captureThreadLocals();         }          @Override         public T call() throws Exception {             Map, Object> originalThreadLocals = captureThreadLocals();             restoreThreadLocals(threadLocals);             try {                 return actual.call();             } finally {                 restoreThreadLocals(originalThreadLocals);             }         }          private Map, Object> captureThreadLocals() {             Map, Object> threadLocals = new HashMap<>();             // Capture current ThreadLocal values             return threadLocals;         }          private void restoreThreadLocals(Map, Object> threadLocals) {             // Restore ThreadLocal values         }     } } 

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...