标签:微服务,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等业务逻辑
其次是服务的调用方:
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:
**/
@Configuration
public class FeignSupportConfig {
/**
* feign请求 *
*
* @return
*/
@Bean
public RequestInterceptor requestInterceptor(){
return new FeignBasicAuthRequestInterceptor();
}
}
来源:https://blog.csdn.net/hzy3344520/article/details/105846487
![](https://www.aspxhome.com/images/zang.png)
![](https://www.aspxhome.com/images/jiucuo.png)
猜你喜欢
- java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对
- Mybatis @SelectKey用法用处主要用来解决主键自增问题用法@SelectKey(statement="SELECT
- 开发环境为android4.1.Handler使用例1这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.
- Feign远程调用Multipartfile参数今天在写业务代码的时候遇到的问题, 前端请求A服务,能正确把参数给到A服务<参数里面包
- C#中如何给Excel添加水印我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的
- 本文实例为大家分享了Unity3D Shader实现扫描显示的具体代码,供大家参考,具体内容如下通过Shader实现,从左向右的扫描显示,可
- 你平时是怎么读取文件的?使用流读取。是的没错,C#给我们提供了非常强大的类库(又一次吹捧了.NET一番),里面封装了几乎所有我们可以想到的和
- Shiro是什么Shiro是一个Java平台的开源权限框架,用于认证和访问授权。具体来说,满足对如下元素的支持:用户,角色,权限(仅仅是操作
- 代理模式代理模式(Proxy Pattern)是一种结构性模式。代理模式为一个对象提供了一个替身,以控制对这个对象的访问。即通过代理对象访问
- 本文实例讲述了C#更改tabControl选项卡颜色的方法。分享给大家供大家参考,具体如下:private void Form1_Load(
- 一、概述IDEA自带的注释模板一般都很简单,然而我们在写代码的时候喜欢把类注释和文档注释写在代码里,既方便自己看所有的参数,也便于以后维护代
- JAVA常用关键字及其用法简要说明Abstract: 抽象的 一个Java语言中的关键字,用在类的声明中来指明一个类是不能被实例化的,但是可
- 前言很多时候,当你以为掌握了事实真相的时间,如果你能再深入一点,你可能会发现另外一些真相。比如面向切面编程的最佳编程实践是AOP,AOP的主
- 工具类-java精确到小数点后6位验证要求,必须精确到小数点后6位,但是后面都是0的话,double会省略0,正则验证不通过,所以有了下面解
- 1. 控件说明SwipeRefreshLayout是google官方推荐使用的下拉刷新的控件,如果用户想通过垂直滑动手势刷新视图的内容,就可
- 本文实例讲述了C#检查指定对象是否存在于ArrayList集合中的方法。分享给大家供大家参考。具体分析如下:C#的ArrayList提供了一
- 前言随着网络技术的发展、计算机应用水平广泛提高,原来系统的时效性、数据的正确性、操作的方便性上都存在不足,已影响到系统的正常使用。经过考察比
- 一.分类从实现的技术上来分类,目前主要有三种技术(或者说有三种产品):1.Java自带的java.util.Timer类,这个类允许你调度一
- PPT中的动画效果可分为已有内置动画以及自定义动画。设置内置动画,只需直接指定动画效果类型即可。本文主要介绍如何实现自定义动画,即自定义形状
- 电话号码的字母组合中等给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下