谷粒商城实战笔记-问题记录-Feign异步调用丢失请求头问题

本文主要是介绍谷粒商城实战笔记-问题记录-Feign异步调用丢失请求头问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 单线程下生效的原理
  • 多线程下Interceptor不生效的原因
  • 解决方案
    • 1,不优雅的方法
    • 2,优雅的方法

在请求多个信息时,我们使用了多线程,这就带来了一个问题,前面我们解决Feign丢失请求头的方案在多线程下,不再有效,丢失请求头的问题再度出现。

在这里插入图片描述

单线程下生效的原理

  1. 请求处理流程
    在单线程环境下,请求的处理流程是顺序的。当一个请求到达时,它会被控制器(Controller)处理。控制器会调用服务(Service)来处理业务逻辑。在这个过程中,请求相关的数据会被存储在ThreadLocal中。

  2. RequestContextHolder
    RequestContextHolder是一个工具类,它提供了获取当前请求相关数据的方法。在单线程环境下,当一个请求被处理时,RequestContextHolder.getRequestAttributes()会返回当前请求的ServletRequestAttributes。这个ServletRequestAttributes包含了请求相关的数据,包括请求头。

  3. RequestInterceptor
    当Feign客户端发送请求时,RequestInterceptorapply方法会被调用。在这个方法中,通过RequestContextHolder.getRequestAttributes()获取当前请求的ServletRequestAttributes,然后将请求头添加到新的请求中。由于在单线程环境下,请求的处理是顺序的,因此RequestInterceptor能够正确地获取到请求头,并将其添加到新的请求中。

多线程下Interceptor不生效的原因

  1. 多线程环境
    在多线程环境下,每个线程都有自己的请求上下文。当一个线程处理请求时,它会将请求相关的数据存储在ThreadLocal中。然而,当这个线程处理完请求后,它会释放这些数据,以便其他线程可以使用ThreadLocal来存储自己的请求数据。

  2. RequestContextHolder
    在多线程环境下,当一个线程处理完请求后,它会释放ThreadLocal中的请求数据。这意味着,当另一个线程处理请求时,它不会访问到前一个线程的请求数据,包括请求头。因此,即使使用了RequestInterceptor,多线程下还是会丢失header头。

  3. Controller和Service是否在同一线程
    在多线程环境下,控制器(Controller)和服务(Service)可能不在同一个线程中。当控制器处理请求时,它会将请求相关的数据存储在ThreadLocal中。然而,当控制器调用服务来处理业务逻辑时,这个请求数据可能会被释放,以便其他线程可以使用ThreadLocal来存储自己的请求数据。因此,即使服务在同一个线程中,它也可能无法访问到控制器的请求数据,包括请求头。

通过以上分析,单线程下生效的原理在于请求的处理是顺序的,RequestInterceptor能够正确地获取到请求头,并将其添加到新的请求中。而多线程下Interceptor不生效的原因在于ThreadLocal的作用域和多线程环境,以及控制器和服务可能不在同一个线程中。

解决方案

1,不优雅的方法

在创建线程的之前把ThreadLocal中内容取出,然后设置到子线程的ThreadLocal中。

在这里插入图片描述
但这样做会侵入业务代码,且每使用一个线程就要写这样一段代码,还会导致大量冗余代码。

2,优雅的方法

创建一个抽象类,实现Runnable方法。

public abstract class MyRunnable implements Runnable{private RequestAttributes requestAttributes;public MyRunnable() {requestAttributes = RequestContextHolder.getRequestAttributes();}public abstract void myRun();@Overridepublic void run() {//每一个线程都来共享之前的请求数据RequestContextHolder.setRequestAttributes(requestAttributes);myRun();}
}

用法如下:
在这里插入图片描述
使用第二种方法,巧妙地把设置对象的工作放在了创建线程对象的构造过程中。

//开启第一个异步任务CompletableFuture<Void> addressFuture2 = CompletableFuture.runAsync(new MyRunnable() {@Overridepublic void myRun() {//1、远程查询所有的收获地址列表List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());confirmVo.setMemberAddressVos(address);}}, threadPoolExecutor);

这篇关于谷粒商城实战笔记-问题记录-Feign异步调用丢失请求头问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111507

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Pandas使用SQLite3实战

《Pandas使用SQLite3实战》本文主要介绍了Pandas使用SQLite3实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1 环境准备2 从 SQLite3VlfrWQzgt 读取数据到 DataFrame基础用法:读

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

SpringBoot启动报错的11个高频问题排查与解决终极指南

《SpringBoot启动报错的11个高频问题排查与解决终极指南》这篇文章主要为大家详细介绍了SpringBoot启动报错的11个高频问题的排查与解决,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一... 目录1. 依赖冲突:NoSuchMethodError 的终极解法2. Bean注入失败:No qu

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1