当前位置: 首页 > news >正文

异步的feign请求报错:No thread-bound request found

接上一篇:https://blog.csdn.net/JFENG14/article/details/153473176?spm=1011.2415.3001.5331

问题:添加FeignHeaderConfig和HystrixConfig后,异步的feign请求报错:No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.

解决方法:

  1. 非 Web 场景下不要尝试读取请求头
    FeignHeaderConfig 已经在 attributes == nullreturn;,这是正确做法。
    然而,Hystrix 线程里 attributes 不再为 null(被你包装过了),但实际请求已经结束(例如异步定时任务),这时 HttpServletRequest 对象已失效,再用它拿 Header 会触发上述异常。

  2. 把“需要透传的 Header”提前摘出来,放到线程变量里
    InheritableThreadLocal(或阿里推荐的 TransmittableThreadLocal)在主线程就把 Header 快照下来;
    后续任何线程(Hystrix、异步、Feign 重试)都读这份“快照”,而不再去碰 RequestContextHolder

1.定义一个快照容器

public final class RequestHeaderSnapshot {private static final InheritableThreadLocal<Map<String, String>> SNAPSHOT =new InheritableThreadLocal<>();/** Web 请求入口时调用:把指定 Header 快照下来 */public static void capture(Set<String> headerNames) {ServletRequestAttributes attr =(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attr == null) {SNAPSHOT.remove();return;}HttpServletRequest req = attr.getRequest();Map<String, String> map = new HashMap<>();headerNames.forEach(h -> {String v = req.getHeader(h);if (StringUtils.isNotBlank(v)) {map.put(h, v);}});SNAPSHOT.set(map);}/** 任何地方获取快照 */public static Map<String, String> get() {return SNAPSHOT.get() == null ? Collections.emptyMap() : SNAPSHOT.get();}/** 请求结束后清理,防止线程复用串数据 */public static void clear() {SNAPSHOT.remove();}
}
2.在 Web 入口(拦截器/过滤器)里拍照
@Component
public class HeaderSnapshotFilter extends OncePerRequestFilter {private static final Set<String> HEADER_NAMES = Set.of("Tenant-Id", "Authorization", "X-Request-Id", "X-User-Id", "X-User-Name");@Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain)throws ServletException, IOException {try {RequestHeaderSnapshot.capture(HEADER_NAMES);chain.doFilter(request, response);} finally {RequestHeaderSnapshot.clear();   // 一定要清理}}
}
3.修改 FeignHeaderConfig,不再直接读 Request
@Bean
public RequestInterceptor headerRequestInterceptor() {return template -> {// 1. 读快照Map<String, String> snapshot = RequestHeaderSnapshot.get();snapshot.forEach(template::header);};
}

✅ 结果

  • Web 场景:主线程拍照 → Feign 在任何线程都能拿到快照。

  • 非 Web 场景(定时任务、MQ):快照为空,Feign 只追加自定义参数,不会抛异常。

  • 无侵入:不用改 Hystrix、Ribbon、异步线程池;快照用完后立即清理,线程安全。

http://www.dtcms.com/a/511219.html

相关文章:

  • 北京建设公司网站建设重庆有网站公司
  • YUV实战案例:一个网络摄像头的工作流程(速通)
  • 深入解析SCT分散加载文件
  • AIGC-Fooocus部署实践:从本地手动配置到云端一键启用的深度剖析
  • 数据结构——最小(代价)生成树
  • NumPy的hstack函数详细教程
  • 020数据结构之优先队列——算法备赛
  • 华为OD-23届考研-测试面经
  • 阿里云网站建设步骤wordpress防止频繁搜索
  • 西宁网站建设哪家公司好东莞seo网站推广
  • 2025年AI IDE的深度评测与推荐:从单一功能效率转向生态壁垒
  • OSS存储的视频,安卓和PC端浏览器打开正常,苹果端打开不播放,什么原因?
  • Spark的shuffle类型与对比
  • 【 论文精读】VIDM:基于扩散模型的视频生成新范式
  • CentOS 7 安装指定内核版本与切换内核版本
  • Spring MVC 拦截器interceptor
  • 如何在 CentOS、Ubuntu 和 Debian 云服务器上安装 Python 3
  • 《金融电子化》:构建金融韧性运行安全体系:从灾备管理到主动防御新范式​​
  • spark组件-spark core(批处理)
  • 进行网站建设视频教程装修网站cms
  • 解决Kali虚拟机中VMnet1(仅主机模式)网卡无法获取IP地址的问题
  • Linux驱动开发笔记(十一)——阻塞和非阻塞IO
  • Docker----快速入门
  • 深度学习8-卷积神经网络-CNN概述-卷积层-池化层-深度卷积神经网络-案例:服装分类
  • 厦门做外贸网站国内十大咨询公司排名
  • 架构设计过去十年与未来十年
  • Nginx 日志轮转
  • 《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署mongodb 7.0.22容器版副本集群》
  • 《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署mongodb 7.0.22容器版分片集群》
  • MongoDB基础与Mongoose ODM