OpenFeign 线程模式下 Threadlocal 变量丢失

lemon发布

/**
 * 解决线程模式下
 * ThreadLocal 失效问题
 *
 * @author lemon
 */
@Configuration
public class HystrixConfig {


    @Bean
    public HystrixConcurrencyStrategy hystrixConcurrencyStrategy() {
        return new HystrixConcurrencyStrategy() {

            private final Logger logger = LoggerFactory.getLogger(HystrixConcurrencyStrategy.class);

            @Override
            public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
                final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
                final int dynamicCoreSize = corePoolSize.get();
                final int dynamicMaximumSize = maximumPoolSize.get();
                if (dynamicCoreSize > dynamicMaximumSize) {
                    logger.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
                            dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ".  Maximum size will be set to " +
                            dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
                    return new TtlThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime.get(), unit, workQueue, threadFactory);
                } else {
                    return new TtlThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime.get(), unit, workQueue, threadFactory);
                }
            }

            @Override
            public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey
                    , HystrixThreadPoolProperties threadPoolProperties) {
                final ThreadFactory threadFactory = getThreadFactory(threadPoolKey);
                final boolean allowMaximumSizeToDivergeFromCoreSize = threadPoolProperties.getAllowMaximumSizeToDivergeFromCoreSize().get();
                final int dynamicCoreSize = threadPoolProperties.coreSize().get();
                final int keepAliveTime = threadPoolProperties.keepAliveTimeMinutes().get();
                final int maxQueueSize = threadPoolProperties.maxQueueSize().get();
                final BlockingQueue<Runnable> workQueue = getBlockingQueue(maxQueueSize);

                if (allowMaximumSizeToDivergeFromCoreSize) {
                    final int dynamicMaximumSize = threadPoolProperties.maximumSize().get();
                    if (dynamicCoreSize > dynamicMaximumSize) {
                        logger.error("Hystrix ThreadPool configuration at startup for : " + threadPoolKey.name() + " is trying to set coreSize = " +
                                dynamicCoreSize + " and maximumSize = " + dynamicMaximumSize + ".  Maximum size will be set to " +
                                dynamicCoreSize + ", the coreSize value, since it must be equal to or greater than the coreSize value");
                        return new TtlThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
                    } else {
                        return new TtlThreadPoolExecutor(dynamicCoreSize, dynamicMaximumSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
                    }
                } else {
                    return new TtlThreadPoolExecutor(dynamicCoreSize, dynamicCoreSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
                }
            }

            private ThreadFactory getThreadFactory(final HystrixThreadPoolKey threadPoolKey) {
                if (!PlatformSpecific.isAppEngineStandardEnvironment()) {
                    return new ThreadFactory() {
                        private final AtomicInteger threadNumber = new AtomicInteger(0);

                        @Override
                        public Thread newThread(Runnable r) {
                            Thread thread = new Thread(r, "hystrix-" + threadPoolKey.name() + "-" + threadNumber.incrementAndGet());
                            thread.setDaemon(true);
                            return thread;
                        }

                    };
                } else {
                    return PlatformSpecific.getAppEngineThreadFactory();
                }
            }



        };
    }

    public static class TtlThreadPoolExecutor extends ThreadPoolExecutor {

        public TtlThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
                                     BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        }
        @Override
        public void execute(Runnable command) {
            super.execute(TtlRunnable.get(command));
        }
    }

}

分类: Java

0 条评论

发表回复

Avatar placeholder

您的邮箱地址不会被公开。 必填项已用 * 标注