软件编程
位置:首页>> 软件编程>> java编程>> 解决微服务feign调用添加token的问题

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

作者:synda@hzy  发布时间:2023-09-11 09:38:05 

标签:微服务,feign,token

微服务feign调用添加token

1.一般情况是这么配置的

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


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
@Slf4j
public 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对象的问题
*
*/
//@Configuration
public 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: true
hystrix:
 command:
   default:
     execution:
       isolation:
         thread:
           timeoutInMilliseconds: 5000  #服务连接成功,但是时间过长,降级方法调用时间   60000   5000

feign微服务的相互调用

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

首先是服务提供方:

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

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

其次是服务的调用方:

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

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

2.编写服务调用接口

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

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

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

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

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


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);
     }
   }
 }
}

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


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:
**/
@Configuration
public class FeignSupportConfig {
 /**
  * feign请求 *
  *
  * @return
  */
 @Bean
 public RequestInterceptor requestInterceptor(){
   return new FeignBasicAuthRequestInterceptor();
 }
}

来源:https://blog.csdn.net/hzy3344520/article/details/105846487

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com