多线程之HardCodedTarget(type=OssFileClient, name=file, url=http://file)异常

摘要: 文档描述了多线程环境下调用Feign客户端OssFileClient时出现的HardCodedTarget异常。异常发生在异步保存文件到ES时,Feign调用未返回预期结果而直接打印了客户端对象。问题分析指出可能原因:1)Feign调用失败但未被捕获;2)异步线程缺少Spring上下文导致认证失败。解决方案包括:1)配置支持上下文传播的线程池TaskDecorator;2)手动传递请求和Security上下文到异步线程。文中提供了ThreadPoolConfig配置类和ContextCopyingTaskDecorator实现,确保主线程上下文能正确传递到异步任务中。

前言
1,异常场景如下,文件上传使用多线程调用微服务OssFile异步保存文件,日志报多线程之HardCodedTarget(type=OssFileClient, name=file, url=http://file)异常

原代码如下

1,主业务代码

    @Override@Transactional(rollbackFor = Exception.class)public Long inserTemergencyProcessingMessage(TemergencyProcessingDto dto) {// 1.获取当前登录人的信息// 2.紧急处理演练文档保存...... // 5.异步添加索引到ESCompletableFuture.runAsync(() -> {log.info("紧急处理演练文档开始异步:{} , {}",temergencyPlanEntity , flIds);temergencyProcessingEsService.indextemergencyProcessing(temergencyPlanEntity, flIds);}, threadCustomPoolExecutor);return planEntity.getId();}

保存ES的代码如下

 @Overridepublic void indextemergencyProcessing(TemergencyPlanEntity planEntity, Set<Long> flIds) {try {// ... 业务代码查询文件信息 // 3.构建ES文档TemergencyPlanEsDocument esDocument = buildEsDocument(planEntity, fileListEntities, fileContentsMap);// 4.索引到ES// 新增文档 - 请求对象IndexRequest indexRequest = new IndexRequest("temergencn_plans").id(planEntity.getId().toString());// 添加文档数据,数据转换为Json...} catch (IOException e) {log.error("...的ES失败,...的id是:{} ", planEntity.getId(), e);}}

2,错误日志如下

… … fiIds:[54]2025-08-26 18:52:52.905 [pool-2-thread-1] INFO com.xx.xxxefileapi.service.impl.TemergencyProcessingEsService - smartFileClient 获取的数据是:HardCodedTarget(type=OssFileClient, name=file, url=http://file)
2025-08-26 18:52:52.910 [http-nio-16710-exec-3] INFO

3,问题排查思路

1,发现异步线程中调用了smartOssFileClient.queryFileListByIds(flIds),但是在日志中并没有打印出调用该Feign客户端后的结果(即没有打印fileListEntitiesr 返回的数据是:),而是直接打印了ossFileClient对象,显示为HardCodedTarget(type=OssFileClient, name=file, url=http://file)。

1.1 Feign客户端调用失败,但是没有异常捕获,但是查看代码,在indextemergencyProcessing方法中捕获的是IOException,而Feign调用可能抛出的是FeignException,属于RuntimeException,所以没有被捕获,但奇怪的是也没有看到异常日志。

1.2 线程上下文问题:Feign调用通常依赖于Spring的上下文(如请求拦截器、负载均衡等),而在异步线程中,可能无法获取到正确的上下文,导致Feign调用失败。
但是,从日志中看到,在异步线程中打印了ossFileClient对象,说明该对象不是null,而且Feign客户端已经正常创建。

另外,注意到在异步线程打印日志的同时,主线程(http-nio-16710-exec-3)打印了AuthInterceptor的后置处理日志。这提示我们可能异步线程中缺少了某些上下文,例如安全上下文、请求头等,导致Feign调用时没有正确的认证信息。

解决方案:
1,确保Feign调用能够传递必要的请求头(如认证信息)。可以使用Feign的拦截器,或者自定义请求拦截器,在异步线程中手动设置请求头。
2,检查异步线程的线程池配置,是否支持上下文传播。如果你使用的是Spring Boot 3.x,可以考虑使用Spring Boot的异步支持并配置任务装饰器(TaskDecorator)来传递上下文。如果是较低版本,可以考虑使用其他方式(如InheritableThreadLocal)或者手动传递上下文。

4,手动传递上下文到异步线程

1,配置线程支持上下文传递

如果使用自定义线程池(threadCustomPoolExecutor),需确保其支持上下文传播。推荐使用 TaskDecorator:


import lombok.Data;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskDecorator;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;/*** @author psd*/
@Data
@Configuration
public class ThreadPoolConfig {@Bean("threadCustomPoolExecutorAsync")public ThreadPoolTaskExecutor threadCustomPoolExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(coreSize);executor.setMaxPoolSize(maxSize);executor.setQueueCapacity(blockQueueSize);executor.setTaskDecorator(new ContextCopyingTaskDecorator());executor.setThreadNamePrefix("Async-Executor-");executor.initialize();return executor;}public static class ContextCopyingTaskDecorator implements TaskDecorator {@Overridepublic @NotNull Runnable decorate(@NotNull Runnable runnable) {// 捕获主线程上下文RequestAttributes requestContext = RequestContextHolder.currentRequestAttributes();SecurityContext securityContext = SecurityContextHolder.getContext();return () -> {try {// 将主线程上下文设置到异步线程RequestContextHolder.setRequestAttributes(requestContext, true);SecurityContextHolder.setContext(securityContext);runnable.run();} finally {// 清理异步线程上下文RequestContextHolder.resetRequestAttributes();SecurityContextHolder.clearContext();}};}}
}
2,手动传递上下文到异步线程

@Resource
private ThreadPoolExecutor threadCustomPoolExecutor;@Override
@Transactional(rollbackFor = Exception.class)
public Long inserTemergencyProcessingMessage(ContingencyPlanDto dto) {// ... [原有代码] ...// 捕获当前请求上下文和安全上下文RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();SecurityContext securityContext = SecurityContextHolder.getContext();// 5.异步添加索引到ESCompletableFuture.runAsync(() -> {try {// 恢复上下文到异步线程RequestContextHolder.setRequestAttributes(requestAttributes);SecurityContextHolder.setContext(securityContext);log.info("应急预案开始异步:{} , {}", planEntity, flIds);temergencyProcessingEsService.indextemergencyProcessing(temergencyPlanEntity, flIds);} finally {// 清理上下文避免内存泄漏RequestContextHolder.resetRequestAttributes();SecurityContextHolder.clearContext();}}, threadCustomPoolExecutor);return planEntity.getId();
}

最终代码调试到重点:
1,手动传递并恢复上下文(RequestContext + SecurityContext)
2,配置线程池的TaskDecorator确保上下文传播。
3,确认Feign拦截器正确配置用于 token 传递。

喜欢我的文章记得点个在看,或者点赞,持续更新中ing…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95939.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95939.shtml
英文地址,请注明出处:http://en.pswp.cn/web/95939.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机视觉(十二):人工智能、机器学习与深度学习

人工智能 (AI)&#xff1a;宏大的目标 人工智能是最广泛、最宏大的概念&#xff0c;它的目标是让机器能够模仿人类的智能行为&#xff0c;例如&#xff1a; 推理&#xff1a;像下棋程序一样&#xff0c;通过逻辑来做决策。规划&#xff1a;为实现一个目标而制定步骤&#xff0c…

容器元素的滚动条回到顶部

关闭再打开后&#xff0c;容器元素的滚动条回到顶部解决方法&#xff1a;1、通过打开开发者工具&#xff08;F12&#xff09;&#xff0c;找到滚动条所属元素为 el-textarea__inner&#xff0c;其父类 class"el-textarea content"2、代码&#xff0c;通过元素的方法 …

分布式专题——2 深入理解Redis线程模型

1 Redis 简介 1.1 Redis 是什么&#xff1f; Redis 全称 Remote Dictionary Server&#xff08;远程字典服务&#xff09;&#xff0c;是一个开源的高性能 Key-Value 数据库&#xff1b; 官网&#xff1a;Redis - The Real-time Data Platform&#xff1b; 引用官网上的⼀个…

simd学习

如何查看cpu是否支持simd&#xff1f;# 检查特定指令集 grep -o avx2 /proc/cpuinfo | head -1 # 检查AVX2 grep -o sse4 /proc/cpuinfo | head -1 # 检查SSE4 grep -o avx512 /proc/cpuinfo | head -1 # 检查AVX512gcc编译选项&#xff0c;增加支持simd-mavx2 -D__AVX2__SS…

LabVIEW汽车发动机振动测试

以某型号四缸汽油发动机为测试对象&#xff0c;借助 LabVIEW 平台与高精度数据采集硬件&#xff0c;开展发动机全工况振动测试。通过实时采集缸体、曲轴箱关键部位振动信号&#xff0c;分析振动特征与故障关联&#xff0c;验证发动机运行稳定性&#xff0c;为后期优化设计提供数…

android 四大组件—Service

启动服务startService//启动服务&#xff0c;通过类名 Intent intent new Intent(this, WiFiAutoLinkService.class); startService(intent); //通过字符串启动 Intent intent new Intent(); intent.setAction("com.launcher.app"); intent.setPackage("com.l…

https + 域名 + 客户端证书访问模式

项目使用金融云部署&#xff0c;对外暴露IP访问&#xff0c;因安全合规要求必须使用域名访问&#xff0c;但公司又不提供域名。故&#xff0c;改为 https 域名 客户端证书双向认证 访问模式&#xff0c;大大提升安全性。 1. 密钥文件类型 .key、.csr、.cer&#xff08;或 .cr…

ICPC 2023 Nanjing R L 题 Elevator

[ProblemDiscription]\color{blue}{\texttt{[Problem Discription]}}[Problem Discription] 来源&#xff1a;洛谷。侵权则删。 [Analysis]\color{blue}{\texttt{[Analysis]}}[Analysis] 贪心。优先运送楼层高的货物&#xff0c;在能装下的情况下尽量多装。 因为运送货物的代价…

81-dify案例分享-零代码用 Dify 使用梦 AI 3.0 多模态模型,免费生成影视级视频

1.前言 即梦AI作为字节跳动旗下的AI绘画与视频生成平台&#xff0c;近年来不断推出新的模型和功能&#xff0c;以提升用户体验和创作能力。 即梦AI 3.0是即梦AI的最新版本&#xff0c;于2025年4月发布&#xff0c;标志着其在中文生图模型上的重大升级。该版本不仅在中文生图能…

SQL 进阶指南:视图的创建与使用(视图语法 / 作用 / 权限控制)

在 SQL 操作中&#xff0c;你是否遇到过 “频繁查询多表关联的固定结果”“不想让他人看到表中的敏感字段” 这类问题&#xff1f;比如 “每周都要查‘技术部员工的姓名、职位、薪资’”&#xff0c;每次都写多表关联语句很麻烦&#xff1b;又比如 “给实习生开放数据查询权限&…

【全部更新完毕】2025数学建模国赛C题思路代码文章高教社杯全国大学生数学建模-NIPT 的时点选择与胎儿的异常判定

B题全部更新完毕 包含完整的文章全部问题的代码、结果、图表 完整内容请看文末最后的推广群NIPT 的时点选择与胎儿的异常判定 摘要 在问题一中&#xff0c;我们以无创产前检测&#xff08;NIPT&#xff09;数据为研究对象&#xff0c;围绕“胎儿 Y 染色体浓度”(记为 (V)) 随孕…

Redis(43)Redis哨兵(Sentinel)是什么?

Redis Sentinel&#xff08;哨兵&#xff09;是一种用于管理 Redis 实例的高可用性解决方案。它提供了监控、通知和自动故障转移等功能&#xff0c;确保 Redis 服务在发生故障时能够自动恢复&#xff0c;提供高可用性和可靠性。以下是详细介绍 Redis Sentinel 的功能及其代码示…

蓓韵安禧DHA纯植物藻油纯净安全零添加守护母婴健康

在母婴健康领域&#xff0c;选择合适的营养补充品至关重要。纯植物藻油DHA源自纯净藻类&#xff0c;有效规避了海洋重金属污染的风险&#xff0c;确保安全无隐患。配方坚持零添加香精、色素和防腐剂&#xff0c;避免不必要的化学物质摄入&#xff0c;让妈妈和宝宝更安心。同时&…

钉钉 AI 深度赋能制造业 LTC 全流程:以钉钉宜搭、Teambition 为例

制造业 LTC 流程痛点剖析​在制造业&#xff0c;线索到现金&#xff08;LTC&#xff0c;Lead to Cash&#xff09;的全流程包含从潜在客户线索的发现、商机培育、销售转化、订单执行到最终收款的一系列复杂环节。传统制造业在这一流程中面临诸多挑战&#xff1a;客户需求的多样…

理解UE4中C++17的...符号及enable_if_t的用法及SFINAE思想

下面是一段C17的代码&#xff1a;//函数1&#xff1a;template <typename... BufferTypes,std::enable_if_t<std::conjunction<CanAppendBufferType<std::decay_t<BufferTypes>>...>::value> * nullptr> inline explicit FCompositeBuffer(Buff…

安全419正式公布《甲方安全建设精品采购指南》案例首推运营商行业数据安全核心推荐厂商

在数字经济加速渗透与《网络数据安全管理条例》全面实施的双重背景下&#xff0c;运营商作为数据要素流通的核心枢纽&#xff0c;其安全防护体系建设已成为数字基础设施保障的关键环节。近日&#xff0c;安全 419 正式公布《甲方安全建设精品采购指南》&#xff0c;从近 300 个…

基础词根-汇总

ros rus粗糙 ris cos cus cis切lite文字 late面 侧面ven 来 cess走/agdotect 覆盖 covercele 聚集 加速 gre 聚集&#xff0c;accumu聚集gress 抵达 靠近&#xff0c;aggressive侵略性humor humir 大地 土地chron 时间 time&#xff0c;宇宙的宙lumi 光lightviv vil volun vot/…

JVM中常见的GC垃圾收集器

文章目录 目录 1. Serial GC&#xff08;串行收集器&#xff09; 2. Parallel GC&#xff08;并行收集器&#xff09; 3. CMS&#xff08;Concurrent Mark-Sweep&#xff0c;并发标记 - 清除&#xff09; 4. G1&#xff08;Garbage-First&#xff0c;垃圾优先&#xff09; …

嵌入式C语言之链表冒泡排序

链表冒泡排序一是可以交换指针域的值&#xff0c;二是可以交换指针typedef struct st_node{int score;struce st_node *next;}Node,*LinkList;LinkList createList(){Node *head (Node *)malloc(sizeof(Node));if(NULL head){printf("内存分配失败!"):return NULL;…

远场代码学习_FDTD_farfield

项目4.2 farfield3d - Script command在3D模拟中将给定的功率或场剖面监视器或直线数据集投射到远场。返回电场强度|E| 2。语法描述 out farfield3d("mname",f, na, nb, illumination, periodsa, periodsb, index, direction)&#xff1b; 将给定的功率或场分布监…