微服务之间的认证(令牌传递)
在使用拦截器进行微服务之间的令牌传递时,我在获取当前线程所有的request属性数据时遇到了 attributes始终为空的情况,经过反复检查代码排查逻辑,仍找不到问题所在。
最终我在琢磨hystrix时发现:如果使用Feign并开启熔断,则默认会采取线程池隔离,而feign调用和请求的线程不属于同一个线程,无法获取请求的线程数据,最终会导致无法获取请求的线程数据,会造成空指针异常。
我们知道微服务与微服务之间实现认证,只需要将用户传递的令牌Authorization传递给其他微服务即可。如果微服务之间相互调用采用的是Feign模式,可以创建一个拦截器(RequestInterceptor ),每次执行请求之间,将令牌添加到头文件中即可传递给其他微服务,代码如下
public class FeignInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate requestTemplate) {
try {
//使用RequestContextHolder工具获取request相关变量
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
//取出request
HttpServletRequest request = attributes.getRequest();
//获取所有头文件信息的key
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
//头文件的key
String name = headerNames.nextElement();
//头文件的value
String values = request.getHeader(name);
//将令牌数据添加到头文件中
requestTemplate.header(name, values);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
那么如果微服务之间如果开启了熔断限流,此时则会出现空指针异常
解决方案:hystrix隔离策略换为SEMAPHORE(信号量隔离)
对比一下两种隔离策略的区别: