Feign+Hystrix线程池隔离导致RequestContextHolder丢失上下文

版本修订人修订内容修订日期
V1.0王旭创建文档2023-02-21

一、场景

新增建议场景管理员时,调用了授权的接口,接口是通过token获取的tanentId。
而Feign远程调用会丢失请求头导致报错:授权服务不可用。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、原因及分析

1.进入feign远程调用的源码中
在这里插入图片描述

2.进入invoke方法 请求模板在executeAndDecode方法中被执行
在这里插入图片描述

3.Request在targetRequest被构建
在这里插入图片描述

4.通过遍历拦截器进行构建

在这里插入图片描述

5.SynchronousMethodHandler的构造方法私有 通过create方法创建

在这里插入图片描述

在这里插入图片描述

6.初始requestInterceptors为空 但加入了@RequestHeader spring通过CGLIB进行了增强
在这里插入图片描述

三、解决方法:

1.与上面一样 加入RequestHeader的Authorization属性 但每次远程调用都可能出现同样的问题
2.自定义拦截器,对远程调用进行增强,可以一次性解决问题
在这里插入图片描述
3.这样操作实际未生效,继续排查

四、排查未解决原因

原因及分析
1.打印主线程和拦截器中的线程号 发现不是同一个线程 推断每次远程调用都会创建新线程
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.RequestContextHolder内部的数据共享默认通过ThreadLocal来实现 故不同线程之间无法共享数据
在这里插入图片描述

在这里插入图片描述

3.通过查看配置文件 发现feign调用时启用了hystrix hystrix的隔离策略为Thread 每次远程调用会创建一个新线程
在这里插入图片描述

在这里插入图片描述

4.为了解决丢失上下文的问题 在远程调用前添加 保证在拦截器中能读取到

RequestContextHolder.setRequestAttributes(RequestContextHolder.currentRequestAttributes(),true);

在这里插入图片描述

RequestContextHolder中InheritableThreadLocal分析

https://www.jianshu.com/p/dffb197e2e53

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值