SpringCloud-Feign Feign转发请求头,(防止session失效)

[SpringCloud-Feign] Feign转发请求头,(防止session失效)

import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**

  • 自定义Feign的隔离策略;

  • 在转发Feign的请求头的时候,如果开启了Hystrix,Hystrix的默认隔离策略是Thread(线程隔离策略),因此转发拦截器内是无法获取到请求的请求头信息的,可以修改默认隔离策略为信号量模式:hystrix.command.default.execution.isolation.strategy=SEMAPHORE,这样的话转发线程和请求线程实际上是一个线程,这并不是最好的解决方法,信号量模式也不是官方最为推荐的隔离策略;另一个解决方法就是自定义Hystrix的隔离策略,思路是将现有的并发策略作为新并发策略的成员变量,在新并发策略中,返回现有并发策略的线程池、Queue;将策略加到Spring容器即可;

  • @author mozping

  • @version 1.0

  • @date 2018/7/5 9:08

  • @see FeignHystrixConcurrencyStrategyIntellif

  • @since JDK1.8
    */
    @Component
    public class FeignHystrixConcurrencyStrategyIntellif extends HystrixConcurrencyStrategy {

    private static final Logger log = LoggerFactory.getLogger(FeignHystrixConcurrencyStrategyIntellif.class);
    private HystrixConcurrencyStrategy delegate;

    public FeignHystrixConcurrencyStrategyIntellif() {
    try {
    this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
    if (this.delegate instanceof FeignHystrixConcurrencyStrategyIntellif) {
    // Welcome to singleton hell…
    return;
    }
    HystrixCommandExecutionHook commandExecutionHook =
    HystrixPlugins.getInstance().getCommandExecutionHook();
    HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance().getEventNotifier();
    HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance().getMetricsPublisher();
    HystrixPropertiesStrategy propertiesStrategy =
    HystrixPlugins.getInstance().getPropertiesStrategy();
    this.logCurrentStateOfHystrixPlugins(eventNotifier, metricsPublisher, propertiesStrategy);
    HystrixPlugins.reset();
    HystrixPlugins.getInstance().registerConcurrencyStrategy(this);
    HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
    HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
    HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
    HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
    } catch (Exception e) {
    log.error(“Failed to register Sleuth Hystrix Concurrency Strategy”, e);
    }
    }

    private void logCurrentStateOfHystrixPlugins(HystrixEventNotifier eventNotifier,
    HystrixMetricsPublisher metricsPublisher, HystrixPropertiesStrategy propertiesStrategy) {
    if (log.isDebugEnabled()) {
    log.debug(“Current Hystrix plugins configuration is [” + “concurrencyStrategy [”
    + this.delegate + “],” + “eventNotifier [” + eventNotifier + “],” + “metricPublisher [”
    + metricsPublisher + “],” + “propertiesStrategy [” + propertiesStrategy + “],” + “]”);
    log.debug(“Registering Sleuth Hystrix Concurrency Strategy.”);
    }
    }

    @Override
    public Callable wrapCallable(Callable callable) {
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    return new WrappedCallable<>(callable, requestAttributes);
    }

    @Override
    public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
    HystrixProperty corePoolSize, HystrixProperty maximumPoolSize,
    HystrixProperty keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {
    return this.delegate.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize, keepAliveTime,
    unit, workQueue);
    }

    @Override
    public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
    HystrixThreadPoolProperties threadPoolProperties) {
    return this.delegate.getThreadPool(threadPoolKey, threadPoolProperties);
    }

    @Override
    public BlockingQueue getBlockingQueue(int maxQueueSize) {
    return this.delegate.getBlockingQueue(maxQueueSize);
    }

    @Override
    public HystrixRequestVariable getRequestVariable(HystrixRequestVariableLifecycle rv) {
    return this.delegate.getRequestVariable(rv);
    }

    static class WrappedCallable implements Callable {
    private final Callable target;
    private final RequestAttributes requestAttributes;

     public WrappedCallable(Callable<T> target, RequestAttributes requestAttributes) {
         this.target = target;
         this.requestAttributes = requestAttributes;
     }
    
     @Override
     public T call() throws Exception {
         try {
             RequestContextHolder.setRequestAttributes(requestAttributes);
             return target.call();
         } finally {
             RequestContextHolder.resetRequestAttributes();
         }
     }
    

    }
    }

这里参考的博客,感谢这位大牛:https://blog.csdn.net/Crystalqy/article/details/79083857

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值