默认spring-boot 微服务中 用feign来做服务间调用,是不会携带token传递的。为了能让服务间调用的时候带上token,需要进行配置,增强resTemplate
 

1、先实现请求拦截器

/**
* feign配置token
*/
@Configuration
public class FeignRequestInterceptor implements RequestInterceptor { @Override
public void apply(RequestTemplate requestTemplate) {
// 这里可以添加feign请求的全局参数
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes == null || attributes.getRequest() == null) {
return;
}
HttpServletRequest request = attributes.getRequest();
requestTemplate.header("token", request.getHeader("token"));
requestTemplate.header("feignClient", "ifaas-hotel-robot-platform"); }
}
 

2.在@FeignClient接口里添加configuration = {FeignConfig.class}

@FeignClient(name="被调用的服务名", configuration={FeignRequestInterceptor .class})
由于feign的熔断器hystrix的隔离策略的原因,feign调用线程和主线程隔离了,请求上下文不共用,导致feign拦截器中 RequestContextHolder.getRequestAttributes()为空
 
原因:
此属性指示HystrixCommand.run()执行哪种隔离策略,是以下两种选择之一:
  • THREAD —它在单独的线程上执行,并发请求受线程池中线程数的限制
  • SEMAPHORE —它在调用线程上执行,并发请求受信号量限制
 

3、解决feign中RequestContextHolder.getRequestAttributes()为null方案有两种:

3.1、修改隔离策略:默认是 采用THREAD ,修改成SEMAPHORE 即可,但是不推荐这种做法,因为并发请求收到限制。

 

3.2、自定义feign的并发策略 继承HystrixConcurrencyStrategy,然后重写wrapCallable方法。如下:

import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import java.util.concurrent.Callable; /**
* Created by YangGuanRong
* date: 2022/3/8
*/
@Slf4j
@Primary
@Component
public class CustomFeignHystrixConcurrencyStrategy extends HystrixConcurrencyStrategy { public CustomFeignHystrixConcurrencyStrategy() {
try { HystrixPlugins.getInstance().registerConcurrencyStrategy(this); } catch (Exception e) {
log.error("Failed to register Sleuth Hystrix Concurrency Strategy", e);
}
} @Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
return new WrappedCallable<>(callable, requestAttributes);
} 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;
} /**
* feign opens the fuse (hystrix): feign.hystrix.enabled=ture, and uses the default signal isolation level,
* The HttpServletRequest object is independent of each other in the parent thread and the child thread and is not shared.
* So the HttpServletRequest data of the parent thread used in the child thread is null,
* naturally it is impossible to obtain the token information of the request header In a multithreaded environment, call before the request, set the context before the call
*
* feign启用了hystrix,并且feign.hystrix.enabled=ture。采用了线程隔离策略。
* HttpServletRequest 请求在对象在父线程和子线程中相互独立,且不共享
* 所以父线程的 HttpServletRequest 在子线程中为空,
* 所以通常 在多线程环境中,在请求调用之前设置上下文
* @return T
* @throws Exception Exception
*/
@Override
public T call() throws Exception {
try {
// Set true to share the parent thread's HttpServletRequest object setting
RequestContextHolder.setRequestAttributes(requestAttributes, true);
return target.call();
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
}
}

feign服务中调用,传递token的更多相关文章

  1. SpringCloud初体验:三、Feign 服务间调用(FeignClient)、负载均衡(Ribbon)、容错/降级处理(Hystrix)

    FeignOpenFeign Feign是一种声明式.模板化的HTTP客户端. 看了解释过后,可以理解为他是一种 客户端 配置实现的策略,它实现 服务间调用(FeignClient).负载均衡(Rib ...

  2. Spring Cloud Feign 服务消费调用(三)

    序言 Spring Cloud Netflix的微服务都是以HTTP接口的形式暴露的,所以可以用Apache的HttpClient或Spring的RestTemplate去调用 而Feign是一个使用 ...

  3. 在Delphi开发的服务中调用指定应用程序

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://fxh7622.blog.51cto.com/63841/529033 在很多时候 ...

  4. Spring Cloud OAuth2.0 微服务中配置 Jwt Token 签名/验证

    关于 Jwt Token 的签名与安全性前面已经做了几篇介绍,在 IdentityServer4 中定义了 Jwt Token 与 Reference Token 两种验证方式(https://www ...

  5. 代码书写C++ 中调用传递与指针传递根本区别

    从概念上讲.指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变.而引用是一个别名,它在逻辑上不是独立的,它的存在具有依 ...

  6. 【多线程】java多线程Completablefuture 详解【在spring cloud微服务之间调用,防止接口超时的应用】【未完成】

    参考地址:https://www.jianshu.com/p/6f3ee90ab7d3 示例: public static void main(String[] args) throws Interr ...

  7. DELPHI编写服务程序总结(在系统服务和桌面程序之间共享内存,在服务中使用COM组件)

    DELPHI编写服务程序总结 一.服务程序和桌面程序的区别 Windows 2000/XP/2003等支持一种叫做“系统服务程序”的进程,系统服务和桌面程序的区别是:系统服务不用登陆系统即可运行:系统 ...

  8. Spring Cloud中Feign如何统一设置验证token

    代码地址:https://github.com/hbbliyong/springcloud.git 原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过 ...

  9. SpringCloud系列——Feign 服务调用

    前言 前面我们已经实现了服务的注册与发现(请戳:SpringCloud系列——Eureka 服务注册与发现),并且在注册中心注册了一个服务myspringboot,本文记录多个服务之间使用Feign调 ...

随机推荐

  1. Vue.js开发环境配置与项目创建

    一.需要安装和配置 Node.js 与 npm 二.Vue.js的安装或cdn引用: ·cdn引用(不适合项目开发): <script src="https://cdn.jsdeliv ...

  2. js 保护网站

    转载请注明来源:https://www.cnblogs.com/hookjc/ <!--禁止鼠标右键代码--><noscript><iframe src=*.html&g ...

  3. UDP数据包最大传输长度

    概念以太网(Ethernet)数据帧的长度必须在46-1500字节之间,这是由以太网的物理特性决定的.这个1500字节被称为链路层的MTU(最大传输单元). 但这并不是指链路层的长度被限制在1500字 ...

  4. nginx入门教程 (转)

    1.Nginx 状态码配置和错误文件 server { # 配置访问 /test.js 时报 403 错 location /test.js { return 403; } # 配置访问 /404 时 ...

  5. 位运算符、|和||、&和&&的区别

    一.位运算符操作的都是整数类型 1.<<:左移,在一定范围内向左移动n位,相当于乘以2的n次幂 左移不管是正数还是负数,都是在后面添0: 2.>>:右移,在一定范围内向右移动n ...

  6. Nginx的优化与防盗链

    Nginx的优化与防盗链 1.隐藏版本号 2.修改用户与组 3.缓存时间 4.日志切割 5.连接超时 6.更改进程数 7.配置网页压缩 8.配置防盗链 9.fpm参数优化 1.隐藏版本号: 可以使用 ...

  7. SQL 游标 指针

    DECLARE @radioScoreRate decimal DECLARE @checkScoreRate decimal DECLARE @judgeScoreRate decimal DECL ...

  8. 已完成的python项目-环境离线部署

    python环境离线部署 当前生产环境中,有很多基于python开发的工具需要使用. 由于python工具往往涉及到很多依赖,在线状态下,可以通过pip requirements来管理安装. 但有时候 ...

  9. postman python疑难

    例子1:postman请求时会将默认的headers的content-type替换成Content-Type,而直接使用python的request则不行,服务器端就会接收到错误的Content-Ty ...

  10. 1Appium Desktop 的简单应用

    由于Appium Desktop出来了,所以使用appium要比以前简单许多,现在根据以前的文章针对Appium Desktop做下修改更新 之前文章链接:https://testerhome.com ...