【解决问题思路分析】记录hutool默认使用服务端上次返回cookie的问题解决思路

news2024/11/15 22:37:49

背景:

本服务需要调用第三方接口获取数据,首先调用public-key接口获取公钥,然后用公钥加密密码,将用户名和密码传入/ticket接口,获取Cookie和response body中的token。
请添加图片描述

排查思路

由于是调用第三方接口出现问题,第一步先拉通第三方对接人查看后台日志,对方使用apisix作为api网关,初步判断是对方有不同节点,负载均衡到不同节点而导致的偶发性问题。因此本地使用postman连续发起多次请求,经过50次请求后,每一次都能正确响应结果,此时可推测应该不是由于负载均衡不同节点导致的。

思路二:既然postman每次都能成功,业务系统却会偶发性,说明问题应该是出在本地代码。Debug本地调用流程以期望能够复现302问题,经过多次运行发现,第三方接口返回的cookie和token(下面将cookie和token统称为凭证)会存储在redis中。

代码中判断如果redis中没有凭证,则会重新获取并保存在redis中,如果redis中有凭证则从redis中获取。而redis中没有凭证时,调用第三方接口就获取凭证,再调用第三方业务接口时就一定会报错302,若直接从redis中获取凭证则不会有该问题。此时,可以复现302问题。

既然从redis中获取是正确的,而第一次请求过来就是302错误,我们对比两者的凭证,发现凭证时一模一样的。此时和对接人讨论,怀疑可能第是三方bug:在第一次请求时会查找本地缓存凭证,如果没有的话,则报错302,第二次就能在缓存中找到。为了验证该假设,我们用postman去做第一次调用,发现postman在第一次调用也是能够正常返回的,此时陷入僵局。

思路三:此时,想到通过wireShark抓包查看本地发出的请求有什么区别,但由于是https请求,却看不到header信息。

思路四:由于我们能准确复现302问题,我们再次拉通第三方,期望从对方日志中发现异常,从日志中发现,我们传过去的header中有两个cookie,但是我们代码中只传了一个cookie,此时推测可能是hutool在第一次获取服务端请求时把Cookie缓存起来,下次调用就默认带上Cookie。

HttpRequest req = HttpUtil.createRequest(Method.GET, url) 
							.header("Content-Type", MediaType.APPLICATION_JSON_VALUE)  
							  .header("Cookie", "Cookie")     
							  .header("CSRFPreventionToken", "CSRFPreventionToken") 
							  .header("client_token", "client_token");
HttpResponse response =req.execute();

因此我们使用Apache来调用验证,发现Apache调用并不会出现302问题,此时可确认该问题是由于hutool工具会缓存Cookie,经过debug,发现确实会缓存到threadLocal中。最终,通过在调用/ticket接口并获取完数据后,加上下面一行代码解决。

HttpRequest.getCookieManager().getCookieStore().removeAll();

问题原因

hutool 自动保存了我们 /ticket 返回的 cookie,在这我们重新设置了一遍 token、cookie,导致重复了;然后为什么第二次访问没问题,第一次的request已经结束了,Cookie也就被清掉了,所以只有我们设置的token、Cookie。

总结

本次问题的解决最终找到hutool缓存上一次服务端返回的Cookie是不容易的,中间甚至还用抓包解决,这些解决思路值得记录。通过复盘分析, wireShark是个很好的定位问题工具,需要花点时间学习;开源包的issue是个解决问题的好思路,可以在上面搜索一下;当然还有复现问题,第三方协助,这些都很重要。

最后感谢自己,絮絮叨叨完成了博客,期待写出更多博客哦

参考博客

https://github.com/dromara/hutool/issues/583
https://blog.csdn.net/weixin_30315905/article/details/97599019

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OnlyOffice文档服务器安装及集成使用

OnlyOffice文档服务器安装及集成使用 一、安装1.使用docker安装2.开启防火墙3.配置4.访问测试 二、应用集成1.前端集成(React)(1).安装onlyoffice/document-editor-react(2).使用 ONLYOFFICE 文档 React 组件 2.后台集成(Java)(1) getFile接口(2) callback接口(3) getFile接口和…

SpringBoot拦截器实现

1.定义一个拦截器类,实现HandlerInterceptor接口 创建一个Interceptor类实现HandlerInterceptor接口,重写preHandle(),postHandle(),afterCompletion() 三个方法 如下代码,我们就创建了一个Spring的拦截器 /*** auth…

战神引擎传奇假设教程

战神引擎传奇假设教程 --------------------------------------------------------------------------------------------------- 传奇这款游戏可以说是一代人的回忆,特别是8090后,传奇对他们有着许许多多的难忘的回忆, 随着时代的发展&…

typora常用偏好设置

启用自动保存 关闭拼写检查 插入图片的设置 将图片保存在当前文件夹内 换行设置 关闭换行符的显示功能

LeetCode【155】最小栈

题目&#xff1a; 代码&#xff1a; class MinStack {Deque<Integer> xStack;Deque<Integer> minStack;public MinStack() {xStack new LinkedList<Integer>();minStack new LinkedList<Integer>();minStack.push(Integer.MAX_VALUE);}public voi…

Sub-1G射频收发器soc芯片 UM2080F32 低功耗 32 位 IoTP

UM2080F32是基于 ARM Cortex M0 内核的超低功耗、高性能的、单片集成 (G)FSK/OOK 无线收发机的 32 位SOC 芯片。 UM2080F32 工作于200MHz~960MHz 范围内&#xff0c;支持灵活可设的数据包格式&#xff0c;支持自动应答和自动重发功能&#xff0c;支持跳频操作&#xff0c;支持 …

48 路径总和 III

路经总和 III 题目规定了寻路方向&#xff08;不能折返&#xff0c;是单源向下探路&#xff0c;符合DFS&#xff09;模板1 题解1 DFS更好理解题意的版本 题解2 前缀和&#xff08;重点记忆&#xff09;前缀和 由根结点到当前结点的路径上所有节点的和(不含当前结点) 给定一个二…

面试官:谈谈 Go 内存逃逸机制

大家好&#xff0c;我是木川 一、概念 在一段程序中&#xff0c;每一个函数都会有自己的内存区域存放自己的局部变量、返回地址等&#xff0c;这些内存会由编译器在栈中进行分配&#xff0c;每一个函数都会分配一个栈桢&#xff0c;在函数运行结束后进行销毁&#xff0c;但是有…

【开发日记】Docker搭建Maven私服

文章目录 前言1、拉取镜像2、创建本地目录3、启动容器4、访问5、上传依赖6、项目配置私服 前言 Maven私服是一种特殊的远程仓库&#xff0c;它是架设在局域网内的仓库服务&#xff0c;用来代理位于外部的远程仓库&#xff08;中央仓库、其他远程公共仓库&#xff09;。 在公司…

操作系统实验一:计算机资源信 息分析(Windows 2学时)

一、实验目的 通过实验使学生进一步了解操作系统使用的计算机软硬件环境,掌握进程、线程、内存、文件等基本概念,获得某计算机中的软硬件资源信息。基本能达到下列具体的目标: 掌握获取的计算机硬件信息的方法。掌握获取计算机安装的操作系统信息的方法,分析安装的操作系统…

mybatis逆向工程

目录 第一章、mybatis逆向工程1.1&#xff09;Generator.xml配置文件1.2&#xff09;pom文件中添加mybatis代码自动生成插件1.3&#xff09;双击红色选中命令&#xff0c;生成相关文件</font>1.4&#xff09;成功生成mapper和model&#xff0c;加上注解 友情提醒 先看文…

自动化模式下,企业全面预算管理的提升

近年来&#xff0c;经济世界不确定事件的频频发生&#xff0c;让企业开始关注自身的关键财务弱点。企业在财务能力敏捷性提升的方面仍存在一定的差距&#xff0c;而在数字化转型过程中进行的投资不够&#xff0c;将难以推动企业冲出重围&#xff0c;提高前瞻性和自身预测能力。…

【已解决】socket.gaierror: [Errno -3] Temporary failure in name resolution

问题描述 今天在环境迁移的过程中遇到多个问题&#xff0c;包括ModuleNotFoundError: No module named flask&#xff0c;socket.gaierror: [Errno -3] Temporary failure in name resolution以及Downloading: "https://huggingface.co/gyrojeff/YuzuMarker.FontDetection…

2023前端面试题汇总。

一、CSS 1.说一下CSS的盒模型。 在HTML页面中的所有元素都可以看成是一个盒子盒子的组成&#xff1a;内容content、内边距padding、边框border、外边距margin盒模型的类型&#xff1a; 标准盒模型 margin border padding content 2. IE盒模型 margin content(border p…

微服务必学!RedisSearch终极使用指南,你值得拥有!

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是尘缘&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f449;点击这里&#xff0c;就可以查看我的主页啦&#xff01;&#x1f447;&#x…

【ARM Coresight 系列文章 9.1 -- ITM 仪器化跟踪宏单元详细介绍】

文章目录 1.1 ITM 介绍1.1.1 ITM 功能介绍1.1.2 Cortex-M ITM 的地址范围1.2 ITM 使用1.2.1 ITM 寄存器介绍1.2.2 Cortex-M7 ITM 代码示例1.2.3 Cortex-M33 ITM 代码示例1.1 ITM 介绍 在debug 调试阶段通常都是使用 printf(printk) 来进行进行 log 输出,然后定位问题。那么如…

“Python+”集成技术高光谱遥感数据处理与机器学习深度应用丨高光谱数据预处理-机器学习-深度学习-图像分类-参数回归等12个专题

目录 第一章 高光谱数据处理基础 第二章 高光谱开发基础&#xff08;Python&#xff09; 第三章 高光谱机器学习技术&#xff08;python&#xff09; 第四章 典型案例操作实践 更多应用 本教程提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 涵盖高光谱遥感…

C++ Primer (第五版)-第十二章 动态内存

文章目录 序言12.1 动态内存和智能指针shared_ptr类make_shared函数shared_ptr的拷贝和赋值shared_ptr 自动销毁所管理的对象shared_ptr 还会自动释放相关联的内存定义 StrBlob类直接管理内存指针值和delete动态对象的生存期在知道被释放时为止shared_ptr和new结合使用不要混合…

AD7606模块

了解一下ad7606模块,并学习制作一个。 认识AD7606 先了解一下关元AD7606的信息。&#xff08;芯片手册的内容&#xff09; AD7606 采用 5V 单电源供电&#xff0c;不再需要正负 双电源&#xff0c;并支持真正10V 或5V 的双极性信号输。所有的通道均能以高达 200 kSPS 的速率进…

JVM第二讲:JVM 基础 - 字节码详解

JVM 基础 - 字节码详解 本文是JVM第二讲&#xff0c;JVM 基础-字节码详解。源代码通过编译器编译为字节码&#xff0c;再通过类加载子系统进行加载到JVM中运行。 文章目录 JVM 基础 - 字节码详解1、多语言编译为字节码在JVM运行2、Java字节码文件2.1、Class文件的结构属性2.2、…