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对象的解决方案。文章详细对比了多种方案的优缺点,并给出了高级场景处理、性能优化及安全考量的实用建议,帮助开发者高效解决异步请求传递难题。 阅读详情

相关推荐

手把手教你用三菱PLC控制JET伺服原点:从硬件接线到GXWORKS3程序调试

本文详细介绍了如何使用三菱PLC控制JET伺服系统实现原点回归功能,涵盖硬件接线、参数配置到GX Works3程序调试的全流程。通过实战指南,帮助工程师快速掌握伺服控制技术,提升工业自动化项目的实施效率。

weixin_30642561的博客 535

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

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

weixin_29273849的博客 295

Web前端开发技术:实验14-16

实验14 1. 编写JavaScript程序实现“九九乘法口诀”表,如图14-40所示。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>九九乘法表</title> </head> <body> <h1>九九乘法表</h1> </body> <scri

KslgmrDry的博客 1万+

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

springboot+线程池

yeluowan的博客 2408

手把手教你搞定6脚三位一体数码管的驱动(附C语言源码与Visual Studio调试技巧)

本文详细解析了6脚三位一体数码管的驱动原理与实战技巧,包括引脚复用、动态扫描时序、Visual Studio模拟调试及单片机实现。通过C语言源码示例和调试技巧,帮助开发者快速掌握非标准数码管的驱动方法,提升硬件开发效率。

weixin_30613727的博客 592

5G R18标准:AI/ML如何重塑空口优化与网络架构

人工智能与机器学习正逐步成为通信网络优化的核心技术。其核心原理在于通过数据驱动模型,从海量网络数据中学习信道变化、用户行为等统计规律,替代传统的基于固定规则的优化方法。这一技术范式能显著提升网络性能与效率,尤其在空口资源管理、干扰协调和能耗控制等场景中价值突出。在5G Advanced(R18)标准化框架下,AI/ML被系统性地引入空口设计,聚焦于信道状态信息反馈增强、波束管理与预测等关键用例。通过定义网络侧AI、终端侧AI及联合学习的标准化接口与流程,R18旨在实现跨厂商设备的智能协同,推动无线网络向自适

weixin_35671843的博客 244

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

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

avatar6780的博客 5411

数据挖掘实战-基于情感分析+网络语义分析对泾阳茯茶用户评论进行文本分析

本实验数据集来源于京东商城,使用Python爬虫获取泾阳茯茶商品的用户评论,共计3416条数据,字段有用户ID、用户昵称、IP属地、评论时间、评分、评论内容,共计6个字段信息。'''作者:艾派森csdn主页:https://blog.youkuaiyun.com/m0_64336780时间:2024/5/28'''# 导包import csv# 获取评论q=0.01',q=0.9,en;b_avif=1;b_dw=1412;b_dh=650;areaId=27;

m0_64336780的博客 1万+

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

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

zhk 812

STM32 USB键盘实现指南

在STM32上实现键盘功能可以通过USB HID(人机接口设备)协议来实现,使STM32设备能被计算机识别为标准键盘。通过上述步骤,您可以在STM32上实现一个功能完整的USB键盘。关键点包括:正确配置USB HID设备实现键盘矩阵扫描处理按键事件并生成HID报告优化按键响应和消抖处理添加额外功能如宏键和LED反馈这个实现可以作为基础,进一步扩展为游戏键盘、宏键盘或特殊输入设备。

suny8的专栏 969

超临界二氧化碳再热再压缩布雷顿循环建模与先进控制

超临界二氧化碳布雷顿循环建模与先进控制研究 本文研究了超临界二氧化碳再热再压缩布雷顿循环系统的建模与控制。通过MATLAB/Simscape构建了包含压缩机、透平、回热器等关键组件的动态模型,并设计了基于模型预测控制(MPC)和自抗扰控制(ADRC)的多层控制策略。系统采用转速控制的压缩机、阀门开度控制的透平,以及可变热源加热器,实现了全动态分析。研究结果表明,MPC与ADRC混合控制方案相较于传统PID控制,功率超调降低至0.9%,效率波动控制在±0.08%,扰动恢复时间缩短至12秒。

AI的内部世界的博客 342

多线程系列-ThreadLocal

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

ahao' Blog 1715

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

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

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

zhanglinlang的专栏 402

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

liuhyusb的博客 641

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

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

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

Vic10101的博客 918

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、付费专栏及课程。

余额充值