【SpringCloud系列】OpenFeign调用鉴权及解决由于多线程调用OpenFeign导致的request请求数据丢失的问题
前言SpringCloud微服务之间调用一般使用OpenFeign,认证鉴权一般是通过添加特定的请求头。那么OpenFeign请求其他微服务的时候也要携带特定的请求头,这时候就需要一个拦截器,统一添加请求头。一、请求拦截最简单的方案就是实现feign.RequestInterceptor接口。这样使用OpenFeign请求其他微服务接口的时候就会携带请求头,保证认证通过。@Slf4j@Config
·
前言
SpringCloud微服务之间调用一般使用OpenFeign,认证鉴权一般是通过添加特定的请求头。那么OpenFeign请求其他微服务的时候也要携带特定的请求头,这时候就需要一个拦截器,统一添加请求头。
一、请求拦截
最简单的方案就是实现feign.RequestInterceptor接口。这样使用OpenFeign请求其他微服务接口的时候就会携带请求头,保证认证通过。
@Slf4j
@Configuration
public class CustomFeignRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
HttpServletRequest request = attributes.getRequest();
// 转发token
template.header("token", request.getHeader("token"));
}
}
}
二、多线程调用导致问题
有时候需要多线程调用FeignClient来获取数据,但是会导致无法携带token的异常。经过断点发现,使用多线程调用FeignClient时,在拦截器中无法获取ServletRequestAttributes。因此怀疑是多线程导致Request数据丢失,具体原因未深究。解决办法就是从主线程拿到ServletRequestAttributes,然后在异步线程里再放进Request中。
示例代码如下
//从主线程获取所有request数据
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
executor.execute(() -> {
//其他线程放入request数据
RequestContextHolder.setRequestAttributes(requestAttributes);
});
写在最后的话
多线程调用FeignClient其实很少用到,但是有些场景下为了减少耗时不得不用。当初遇到这个问题,花了好长时间才解决,毕竟万事开头难。希望这篇文档能给你带来一点启发。
更多推荐
已为社区贡献1条内容
所有评论(0)