Spring 异步线程中传递ThreadLocal

使用Async如何传递ThreadLocal及自定义线程池 1. 当使用ThreadLocal存储数据时,程序中使用了@Async异步任务注解,后导致子任务中无法获取到ThreadLocal存储的数据2. 使用@Async注解后默认的线程池最大线程数和队列长度为 Integer.MAX_VALUE,当并发量增高后会导致系统负载飙升甚至系统宕机。 阅读详情

上周熬夜查了一个线上问题,最后复盘会议却没有深入,部门里还是要求快,根据熵增定律,软件系统需要定期注入能力,以维持系统稳定,如果只求快,那么就是牺牲系统的扩展性、健壮性、稳定性。

后期总结一篇生产环境排查问题指南。

今天主体是一个补丁,设计dubbo 超时,spring 异步方法,spring 异步线程传递ThreadLocal 信息。

一、dubbo 超时怎样

{"code":"9","msg":"服务方法(xxx.xxx.xxx:1.0)业务逻辑出错","body":"java.lang.RuntimeException: com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method execute in the service com.fancv.xxx.ccc.client.DamClient. Tried 1 times of the providers [101.51.21.415:30001] (1/1) from the registry zoo1.wwww.cc:30002 on the consumer 12.50.12.148 using the dubbo version 2.5.3. Last error is: Invoke remote method timeout. method: execute, provider: dubbo://10.50.2.145:30001/com.fancv.xxx.ccc.client.DamClient?anyhost=true&application=fancv-wede-sop&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=dubbo&interface=com.fancv.xxx.ccc.client.DamClient&metadata-type=remote&methods=execute&pid=411&pln=fancv-main-sop-gray&protocol=dubbo&release=2.7.7&retries=-1&revision=1.0.0.gray-SNAPSHOT&side=consumer&timeout=5000&timestamp=1640324905371&version=1.0.0-gray, cause: Waiting server-side response timeout by scan timer. start time: 2021-12-27 18:30:28.986, end time: 2021-12-27 18:30:34.018, client elapsed: 0 ms, server elapsed: 5032 ms, timeout: 5000 ms, request: Request [id=180989, version=2.0.0, twoway=true, event=false, broken=false, data=RpcInvocation [methodName=execute, parameterTypes=[class com.fancv.www.sdk.api.RopRequest], 

报错日志显示 dubbo 服务调用超时,测试反馈页面报错,但是程序逻辑执行成功了。

二、 改进方法

spring 异步调用,一般情况下能利用成熟框架的功能就不要自己造轮子,这里采用spring的 @Async 注解

使用方法自行研究

参考 https://www.jianshu.com/p/2d4b89c7a3f1

三、改进中遇到的问题

发现整个文件复制的业务逻辑流程需要用户的登录状态,显而易见,大多数系统会把用户的登录状态放入在Context 中,使用ThreadLocal 的方式进行传递,那么起了一个异步线程之后,登录信息如果不做任何处理就消失了,程序报错。

1.方法传递,把用户信息当做一个参数 传递的新的线程

简单,容易理解

2.很多场景需要异步调用,那么可以使用一个自定义的注解

拦截件处理加了注解的方法,增加ThreadLocal的传递过程。

或许不就的将来spring 框架会支持。

Spring Boot异步任务里Request对象突然‘消失’?一个参数解决RequestContextHolder.getRequestAttributes()为null 本文深入解析了Spring Boot异步任务中Request对象丢失的问题,揭示了ThreadLocal与请求上下文的关系,并提供了通过`inheritRequestAttributes`参数传递Request对象的解决方案。文章详细对比了多种方案的优缺点,并给出了高级场景处理、性能优化及安全考量的实用建议,帮助开发者高效解决异步请求传递难题。 阅读详情

相关推荐

股票行情接口,最全的接入方法

股票行情接口一般有两种,一种是WebSocket,一种是http,通过WebSocket可以获取逐笔的股票tick数据,实时并且高效;通过http接口可以获取股票行情接口中的股票历史数据;WebSocket是一种高效的双向通信协议,它允许数据的实时推送,避免了不断的轮询请求。其次,WebSocket允许您订阅特定的数据源或股票数据产品,只接收您感兴趣的信息,提高了数据的效率和可用性。通过接入股票行情数据的HTTP接口,您可以将数据导入到自己的分析工具或系统中,进行更深入的数据分析、模型构建和决策支持。

apifinance的博客 3425

Spring异步任务中如何用TaskDecorator安全传递线程上下文(附完整代码示例)

本文深入探讨了在Spring异步编程中,如何利用TaskDecorator接口安全、优雅地传递线程上下文信息,解决用户身份、Trace ID等关键数据在异步任务中丢失的问题。通过完整的代码示例,详细展示了从定义上下文模型、实现MdcTaskDecorator到集成Spring线程池的完整生产级解决方案,确保异步任务的可观测性与数据一致性。

weixin_29273849的博客 295

搭建云流媒体存储服务+直播+gb81818+智能摄像头,海康威视,大华,华为,国标推流,RTSP 拉流 srs

开源项目:https://github.com/ossrs/srs-docker#usage 1.centos7安装编译 Step1:拉git代码,切换到开发分支 git clone https://gitee.com/winlinvip/srs.oschina.git srs && cd srs/trunk && git remote set-url origin https://github.com/ossrs/srs.git && git

jxyk2007的专栏 3534

异步线程中如何传递threadlocal中的信息

springboot+线程池

yeluowan的博客 2408

FTViewSE利用VB脚本制作简易日报表

罗克韦尔SE用VB做的简单的报表

z0800656的博客 3023

Kali Linux实战:用Impacket的secretsdump.py快速提取Windows域控哈希(附避坑指南)

本文详细介绍了如何在Kali Linux中使用Impacket的secretsdump.py脚本快速提取Windows域控哈希,包括环境准备、原理剖析、实战操作及常见问题解决方案。特别适合CTF竞赛和网络信息安全爱好者学习,提升渗透测试效率。

weixin_33670786的博客 410

实现ThreadLocal在异步线程(包括线程池)中传递

JDK提供了本地线程共享的ThreadLocal和在创建线程时可继承的InheritableThreadLocal,但是由于大多数情况都推荐使用线程池来进行异步处理,InheritableThreadLocal就达不到我们的预期。但是可以参考它的实现思路,在进行线程间的传递时(如创建线程或创建Runnable实现类),将与父线程绑定的ThreadLocal值传递给子线程,就可实现父子线程ThreadLocal的传递。

avatar6780的博客 5411

【k8s面试】超详细kubernetes面试题总结,面试必问!(附200道K8s Docker面试真题+答案详解

最近很多小伙伴找我要Linux学习资料,于是我翻箱倒柜,整理了一些优质资源,涵盖视频、电子书、PPT等共享给大家!

2401_83620959的博客 1465

Spring Boot 异步线程间数据传递ThreadLocal

Spring Boot 异步线程间数据传递ThreadLocal

zhk 812

090、Sensor上电时序与帧同步的驱动级实现——以索尼IMX766为例的AVDD/DVDD/IOVDD时序调优

摘要: 本文以索尼IMX766传感器为例,深入探讨了传感器上电时序与帧同步的驱动级实现问题。通过分析某车载项目量产中的高温黑屏故障,揭示了AVDD/DVDD/IOVDD时序偏差导致传感器内部状态机异常的根源。文章详细解读了IMX766三路电源的时序约束(如AVDD与DVDD需在1ms内同步至90%),并提供了驱动代码级实现方案,包括电源使能顺序、延时控制及帧同步配置。针对多摄同步场景,强调了曝光时间寄存器写入一致性的重要性。最后结合产线问题定位经验,提出通过示波器抓取电源波形验证时序合规性的方法。全文聚焦硬

zzfmlxs的博客 259

第七天 Labview进阶(7.3 Teststand简单使用)

TestStand是NI开发的自动化测试管理软件,支持多语言编程和硬件集成,广泛应用于电子产品和工业测试。安装时需注意版本选择,2022版支持离线安装。使用步骤包括:1)创建测试序列文件;2)插入测试动作并配置参数(如选择VI路径、设置变量);3)添加条件判断和延时控制;4)执行测试序列时具备流程控制功能,如失败步骤自动跳过后续测试。该软件能有效提升测试效率与准确性,通过可视化操作实现复杂测试流程管理。

weixin_38637405的博客 1730

多线程系列-ThreadLocal

线程安全-ThreadLocal 前言 共享资源被多个线程同时访问可能出现不安全的事情。线程安全一直是很重要的事情,没处理好线程安全的问题可能导致错误甚至很难复现排查。 常见的解决办法有定义不可变(immutable)变量:例如Java中的String类型、Guava库里的ImmutableCollections。还有就是对访问共享资源的线程加上锁:例如JUC包下的ReentrantLock和JDK自带的synchronized关键字,或者借助Unsafe类来实现的自旋锁。还有一种是保证所有执行的任务都一个

ahao' Blog 1715

GEE:连续变化检测 CCDC 提取断点信息(干扰时间、干扰幅度、干扰次数)

本文将介绍在 Google Earth Engine (GEE) 平台上连续变化检测与分类(Continuous Change Detection and Classification, CCDC)提取扰动时间、干扰幅度、干扰次数信息,并下载到本地的代码。

养乐多的博客 1945

spring boot 异步线程@Async 传递 threadLocal数据

第一步在启动服务加上 @EnableAsync 注解。第三步,增加 线程池。提供给 @Async 用。第二步:导入阿里 线程工具类。@Async 的使用。

zhanglinlang的专栏 401

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

聊聊reactor异步线程的变量传递

本文主要研究下reactor异步线程的变量传递。

liuhyusb的博客 641

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

解决 Spring Security 在异步线程中用户信息丢失的问题

Spring Security 在异步线程中丢失用户信息是一个常见但容易解决的问题。简单项目:使用方案1(手动传递)即可中型项目:建议使用方案2(自定义线程池)大型项目:推荐使用方案3(Spring Security官方方案)或综合方案性能敏感:考虑方案4(避免在异步中使用安全上下文)无论选择哪种方案,都要记住:始终在finally块中清理安全上下文合理配置线程池参数添加适当的监控和日志进行充分的测试。

Vic10101的博客 918

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ThreadLocal常见使用场景

threadLocal常见常见,面试可用!

自救 唯有自强 819

ThreadLocal 上下文

是线程本地存储的工具,核心价值是线程数据隔离。适用场景:线程不安全工具类封装、上下文信息传递。用完即清(remove(),否则可能导致内存泄漏或脏数据。理解的核心是抓住 “线程私有副本” 这一特性,同时注意其在长期存活线程(如线程池)中的使用风险。ThreadLocal 如果想异步,如何实现在异步场景中,由于是与当前线程绑定的,而异步任务会在新线程中执行,直接使用会导致上下文丢失。要实现异步场景下的上下文传递,核心思路是。

学长的猫的博客 508

为什么 @Async 方法中无法使用 ThreadLocal?

摘要: @Async方法因切换线程无法访问原线程的ThreadLocal数据(如用户ID)。解决方案是显式传递参数:将所需数据(单个字段或封装为上下文对象)通过方法参数传入。虽然可通过InheritableThreadLocal自动传递,但推荐参数传递以确保线程安全。核心原则:异步方法需独立获取上下文,避免隐式依赖线程局部变量。

qq_61723836的博客 295

如何在子线程和线程池中使用 ThreadLocal 传输上下文

Java技术架构 2019-01-16 12:17:28 专注于Java领域优质技术号,欢迎关注 作者:晓_魂淡 问题举例 在 Spring 框架中,使用 @Async 注解时,如何获取 ThreadLocal 中的数据? 使用 CompletableFuture.supplyAsync 处理异步中,supplyAsync执行的方法如何获取 ThreadLocal 中的数据? Ex...

u011277123的博客 3955

为什么响应式编程无法从Threadlocal里获取数据?

响应式编程模型(如 Spring WebFlux)和传统的 Servlet 基于线程的模型(如 Spring MVC)在处理请求的方式上有显著不同。在传统的 Spring MVC 应用中,每个请求都是由一个固定的线程处理的,因此可以便利地使用。然而,在响应式编程模型中,因为处理流程可能在多个线程之间切换,所以无法保证整个请求处理链在同一个线程中执行。是跟随响应式流的,并且可以在响应式链中的不同操作和不同线程间保持数据的连贯性。的数据是绑定到特定线程的,当请求处理跳转到新的线程时,原线程的。

主要作为个人的笔记用,Not For Everyone。 956

spring异步线程传递线程上下文

我们直接使用@Async注解,当然你也可以直接使用线程池,效果是一样的 首先我们创建ContextDecorator实现TaskDecorator接口 package com.qimo.omsa.demo.thread; import java.util.Map; import org.springframework.core.task.TaskDecorator; /** * @Description TODO * @Author 姚仲杰#80998699 * @Date 2022/1/30 1

a807719447的专栏 1577

Springcloud 自定义线程池

ThreadConfig.java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.ExecutorService; import java.util.concur...

zhaoyang10的专栏 2898

java多线程造成数据丢失_详解Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失...

在Spring Cloud中我们用Hystrix来实现断路器,Zuul中默认是用信号量(Hystrix默认是线程)来进行隔离的,我们可以通过配置使用线程方式隔离。在使用线程隔离的时候,有个问题是必须要解决的,那就是在某些业务场景下通过ThreadLocal来在线程里传递数据,用信号量是没问题的,从请求进来,但后续的流程都是通一个线程。当隔离模式为线程时,Hystrix会将请求放入Hystrix的线...

weixin_39827034的博客 1827

解决异步任务无法获取到Token中的用户信息问题

Spring Security的SecurityContext基于ThreadLocal实现,异步任务在新线程执行时无法直接获取用户认证信息。解决方法包括:1)手动传递SecurityContext并在任务结束后清除;2)直接传递用户ID等具体信息;3)使用TaskDecorator自动传递上下文。核心是确保上下文正确传递,并在任务完成后及时清理,避免内存泄漏和权限污染。三种方法各有利弊,可根据实际场景选择最合适的方案。

qq_45480682的博客 352
上一篇: mac Gradle idea中启动单元测试
下一篇: 程序员面试系列(1)一名 java面试官内心独白
hamish-wu
博客等级 码龄15年 2814粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值