springcloud 微服务用户传递

springcloud 微服务用户传递

在使用spring cloud的时候,多个微服务之间相互调用。很容易出现用户信息传递或者token传递的情况。

我们实现feign提供的RequestInterceptor加人要传递的数据。

@Configuration
public class TransmitUserFeignClientInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        UserInfo userInfo = UserHandler.get();
        List<String> cookies = new ArrayList<>();
        cookies.add("userId=" + userInfo.getId());
        requestTemplate.header(HttpHeaders.COOKIE, cookies);
    }
}
public class UserHandler {

    static final String SESSION_USERID = "SESSION_USERID";

    private static ThreadLocal<UserInfo> user = new ThreadLocal<UserInfo>() {
        @Override
        protected UserInfo initialValue() {
            return null;
        }
    };

    public static void set(UserInfo userInfo) {
        user.set(userInfo);
    }

    public static UserInfo get() {
        return user.get();
    }

    public static void clear() {
        user.remove();
    }
}

在服务当中在加入过滤器和拦截器,都可以实现对request的拦截,然后取出cookie中的值,后面怎么做不需要所了吧。

太妙了,成功那到cookie。

但是 仅限于feign.hystrix.enabledfalse的时候,如果为true则取到的是NULL。容我默哀3分钟…

这是因为feign开启了hystrix后,hystrix默认使用了线程了隔离策略。

解决方案一:调整隔离策略

将隔离策略改为:SEMAPHORE

hystrix.command.default.execution.isolation.strategy: SEMAPHORE

但是这不是官方推荐的

解决方案二:自定义并发策略

继承HystrixConcurrencyStrategy,重写wrapCallable方法。

@Component
public class RequestHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy {

    private final Logger log = LoggerFactory.getLogger(RequestHystrixConcurrencyStrategy.class);

    private HystrixConcurrencyStrategy delegate;

    public RequestHystrixConcurrencyStrategy() {
        try {
            this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();
            if (this.delegate instanceof RequestHystrixConcurrencyStrategy) {
                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 <T> Callable<T> wrapCallable(Callable<T> callable) {
        return new WrappedCallable(callable, UserHandler.get());
    }

    @Override
    public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixProperty<Integer> corePoolSize, HystrixProperty<Integer> maximumPoolSize, HystrixProperty<Integer> keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> 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<Runnable> getBlockingQueue(int maxQueueSize) {
        return this.delegate.getBlockingQueue(maxQueueSize);
    }

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

    static class WrappedCallable<T> implements Callable<T> {

        private final Callable<T> targer;
        private final UserInfo userInfo;

        public WrappedCallable(Callable<T> targer, UserInfo userInfo) {
            this.targer = targer;
            this.userInfo = userInfo;
        }

        @Override
        public T call() throws Exception {
            UserHandler.set(userInfo);
            return targer.call();
        }
    }
}

参考:https://blog.csdn.net/liu_ares/article/details/100371441

你可能感兴趣的:(springcloud,spring,java,spring,boot)