解决微服务feign调用添加token的问题

微服务feign调用添加token1.一般情况是这么配置的

具体的怎么调用就不说了 如下配置,就可以在请求头中添加需要的请求头信息。

package localdate;import feign.RequestInterceptor;import feign.RequestTemplate;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;import org.springframework.stereotype.Component;import org.springframework.web.context.request.RequestAttributes;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;import java.util.Collection;import java.util.Enumeration;import java.util.Iterator;import java.util.Map;/** * feign调用服务时,会丢失请求头信息。需要在这里把认证信息收到添加上去 * @author TRON * @since  2019-11-23 * * */@Configuration@Slf4jpublic class FeignTokenInterceptor implements RequestInterceptor {    @Override    public void apply(RequestTemplate requestTemplate) {        log.info("======上下文中获取原请求信息======");        String token = "without token";        HttpServletRequest request = ((ServletRequestAttributes)                RequestContextHolder.getRequestAttributes()).getRequest();        Enumeration<String> headerNames = request.getHeaderNames();        while (headerNames.hasMoreElements()) {            String headerName = headerNames.nextElement();            String HeadValue = request.getHeader(headerName);            log.info("===原请求头信息=== headName: {}, headValue: {}", headerName, HeadValue);            if (headerName.equals("X-Authorization-access_token")||headerName.equals("x-authorization-access_token")) {                token = HeadValue;            }        }        log.info("=======Feign添加头部信息start======");//        requestTemplate.header("X-Authorization-access_token", token);        requestTemplate.header("X-Authorization-access_token", "tron123456");        log.info("=======Feign添加头部信息end======");    }}

2 .但是,当熔断开启后,原先的这么配置就不起作用了

package localdate;import com.netflix.hystrix.HystrixThreadPoolKey;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.context.annotation.Configuration;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;/** * 自定义并发策略 * 将现有的并发策略作为新并发策略的成员变量 * 在新并发策略中,返回现有并发策略的线程池、Queue * * hystrix.command.default.execution.isolation.strategy=THREAD * Hystrix的默认隔离策略(官方推荐,当使用该隔离策略时,是没办法拿到 ThreadLocal 中的值的,但是RequestContextHolder 源码中,使用了两个ThreadLocal) * hystrix.command.default.execution.isolation.strategy=SEMAPHORE (将隔离策略改为SEMAPHORE 也可以解决这个问题,但是官方并不推荐这个策略,因为这个策略对网络资源消耗比较大) * * 主要是解决当 Hystrix的默认隔离策略是THREAD时,不能通过RequestContextHolder获取到request对象的问题 * *///@Configurationpublic class FeignConfig extends HystrixConcurrencyStrategy {    private static final Logger log = LoggerFactory.getLogger(FeignConfig.class);    private HystrixConcurrencyStrategy delegate;    public FeignConfig() {        try {            this.delegate = HystrixPlugins.getInstance().getConcurrencyStrategy();            if (this.delegate instanceof FeignConfig) {                // 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 <T> Callable<T> wrapCallable(Callable<T> callable) {        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();        return new WrappedCallable<>(callable, requestAttributes);    }    @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 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> 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();            }        }    }}

3 .feign和熔断的配置

feign:  client:    config:      default:        connectTimeout: 5000   #连接超时3秒,连接失败时直接调用降级方法        readTimeout: 100000     #连接成功,处理数据的时间限制10秒 100000   读取时间过短会抛异常java.net.SocketTimeoutException: Read timed out        loggerLevel: full      #日志输出等级  hystrix:    enabled: truehystrix:  command:    default:      execution:        isolation:          thread:            timeoutInMilliseconds: 5000  #服务连接成功,但是时间过长,降级方法调用时间   60000   5000

feign微服务的相互调用

我只是记录服务提供方、消费方的代码编写,配置什么的大家在网上搜,一大堆。

首先是服务提供方:

启动类上加上注解@EnableFeignClients,然后正常的写controller、service等业务逻辑

其次是服务的调用方:

1.首先启动类上加上注解@EnableFeignClients

2.编写服务调用接口

3.编写接口熔断处理方法

4.本人遇到的问题是需要用到调用方的请求头里面的信息,但是在提供方取不到,这时可以通过在调用方增加配置来解决

import feign.RequestInterceptor;import feign.RequestTemplate;import java.util.Enumeration;import javax.servlet.http.HttpServletRequest;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes; /** * @author ydf * @date 2021/5/13 * @description: **/public class FeignBasicAuthRequestInterceptor implements RequestInterceptor {   @Override  public void apply(RequestTemplate requestTemplate) {    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder        .getRequestAttributes();    HttpServletRequest request = attributes.getRequest();    Enumeration<String> headerNames = request.getHeaderNames();    if (headerNames != null) {      while (headerNames.hasMoreElements()) {        String name = headerNames.nextElement();        String values = request.getHeader(name);        requestTemplate.header(name, values);      }    }  }}

import com.jingling.netsign.applet.interceptor.FeignBasicAuthRequestInterceptor;import feign.RequestInterceptor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; /** * @author ydf * @date 2021/5/13 * @description: **/@Configurationpublic class FeignSupportConfig {  /**   * feign请求拦截器   *   * @return   */  @Bean  public RequestInterceptor requestInterceptor(){    return new FeignBasicAuthRequestInterceptor();  }}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

因为在路上你就已经收获了自由自在的好心情。

解决微服务feign调用添加token的问题

相关文章:

你感兴趣的文章:

标签云: