记录一个HttpClient超时连接配置不生效的问题排查过程

httpclient · 浏览次数 : 18

小编点评

## 问题的定位过程: **1. 代码定位问题:** * 首先定位到`InternalHttpClient`中`handleConnectTimeout`方法的代码。 * 在该方法中,我们设置了`connectTimeout`参数,但最终发现 `soTimeOut` 和 `connectTimeOut` 参数的值都设置为-1。 * 这说明配置问题可能在设置 `connectTimeout` 时发生。 **2. 问题的解决:** * 解决方案是验证`connectTimeout`和`soTimeOut`的值是否都设置为-1。 * 如果都设置为-1,则需要重新分析框架代码中所有关于连接超时时间的配置项,以及关于 `requestConfig` 的配置。 * 确认设置是否按照预期。 **3. 代码修改:** * 在`InternalHttpClient`中,添加代码检查`connectTimeout`和`soTimeOut`的值是否都设置为-1。 * 如配置错误,则抛出异常或提示用户进行修正。 **4. 总结:** 通过以上步骤,可以定位并解决代码中的配置问题。并注意,代码的分析过程中要注意细致观察框架的配置逻辑,以及各种参数的作用以及交互关系。

正文

现象

首先有一个被服务由于内存有限,导致巨卡。导致调用他的服务出现线程阻塞。jstack打印线程池如下所示:

开始排查解决问题

第一步:检查代码看是否超时设置是否正确,因为感觉超时设置正确不可能阻塞。

找到注入client的位置:

发现配置没有任何问题,此时感到了一点点慌张。(内心OS: 难不成HttpClient还有BUG, 讲道理这么成熟的框架不应该啊)

第二步:本着高效的原则,百度一下是否有其他人踩过这样的坑了。

咦,这不和遇到的一样吗? 心想搞定。看我jstack栈阻塞堆栈信息,也是有重试的信息,如下图所示:

那么直接更改我们的client注入代码为如下:

以为到这里故事就结束了,开开心心重新部署一下,就去玩其他的了。

噩梦再次上演:几天后,被调用服务再次出现卡顿,然后调用方又阻塞了,what fuck !

老规矩看堆栈信息:

还是熟悉的配方,一样的错误,阻塞在同一个地方。本着高效的原则,GPT了一下,然并没有什么用,都是一些太泛的思路,这玩意干精细活还是有缺陷:

那这样的话,就苦逼了,只能慢慢的撸他源码了。因为服务器卡顿是偶现,还没法调试。找到构建过程如下:

显然实际执行在InternalHttpClient里面。点进去看一下他的执行过程:

发现我们配置的requestConfig可能并未生效,他可能直接从Request里面取,那这显然有可能在调用方给Request手动配置requestConfig。 找到调用处的代码:

显然确实有可能是这个原因,那有了上次的经验,我们要验证一下。由于服务器卡顿是偶现,我们debug看一下是不是走到这里了:

发现都是-1, 那应该就是这个问题了,Request配置,重新打包部署,问题再也没有复现过。over!

题外话

源码定位问题的过程省略了很多,所以看起来解决问题过程似乎很简单。因为框架代码毕竟那么多,我第一步先是猜想要先定位到他超时判断逻辑的代码在哪里,才能知道为什么不生效。定位了很久才发现框架本身并无相关逻辑,他是构建了一个Socket去请求,在socket中有两个时间,一个是soTimeOut(读流超时时间), 一个是connectTimeOut(连接超时时间)。 其在创建socket的时候需要指定connectTimeOut,然后soTimeOut可在发起请求前设置。 当然这也反应出分析问题不够冷静, 忽略了基本的网络常识,这些成熟的框架,一开始就应该思考是不是配置不正确的问题,究其原因也是对框架不够深入了解,不知道具体的某个请求可能还存在可以配置单独的RequestConfig对象,一味的关注CloseableHttpClient的配置去了。

与记录一个HttpClient超时连接配置不生效的问题排查过程相似的内容:

记录一个HttpClient超时连接配置不生效的问题排查过程

现象 首先有一个被服务由于内存有限,导致巨卡。导致调用他的服务出现线程阻塞。jstack打印线程池如下所示: 开始排查解决问题 第一步:检查代码看是否超时设置是否正确,因为感觉超时设置正确不可能阻塞。 找到注入client的位置: 发现配置没有任何问题,此时感到了一点点慌张。(内心OS: 难不成Ht

记一次 .NET 某企业OA后端服务 卡死分析

一:背景 1.讲故事 前段时间有位朋友微信找到我,说他生产机器上的 Console 服务看起来像是卡死了,也不生成日志,对方也收不到我的httpclient请求,不知道程序出现什么情况了,特来寻求帮助。 哈哈,一般来说卡死的情况在窗体程序(WinForm,WPF) 上特别多,在 Console,We

[转帖]调试springboot数据库系统应用时常用debug日志配置, 解决问题缩小范围时常用

https://www.yihaomen.com/article/1853.html 摘要: 用 spring boot 开发应用时,在遇到麻烦问题时,经常会打开debug日志,下面记录一个通用的思路,基于spring boot以及jpa来实现, 一般来说,将root的日志级别设置为log.leve

[转帖]复盘的价值是什么?

https://www.cnblogs.com/imyalost/p/17445773.html 昨天整理记录的笔记,发现了21年做交付时记录的一个思考:为什么要复盘。 之前的文章也聊过一些项目管理以及复盘的话题,主要是复盘的流程,方式以及产出物。2年过去,有了大量的实践和总结后,我对于复盘也有了一

2.4 PE结构:节表详细解析

节表(Section Table)是Windows PE/COFF格式的可执行文件中一个非常重要的数据结构,它记录了各个代码段、数据段、资源段、重定向表等在文件中的位置和大小信息,是操作系统加载文件时根据节表来进行各个段的映射和初始化的重要依据。节表中的每个记录则被称为`IMAGE_SECTION_HEADER`,它记录了一个段的各种属性信息和在文件中的位置和大小等信息,一个文件可以由多个`IMA

[转帖]Nginx更改日志格式为json

https://www.cnblogs.com/lizexiong/p/14989934.html 这里只是简单记录一下主配置文件中的format格式,因为在配置过程中一直不生效,最后发现是因为配置尾部没有加 ; 号导致,所以这里简单做一个记录。 #/etc/nginx/nginx.confuser

[转帖]优秀后端都应该具备的开发好习惯

https://juejin.cn/post/7157508782874968094 前言 大家好,我是捡田螺的小男孩。 记录一下一个优秀的后端开发程序员,应该有哪些好的开发习惯。 公众号:捡田螺的小男孩 github地址,感谢每颗star:github 1.注释尽可能全面,写有意义的方法注释 接口

[转帖]/etc/passwd文件 各个字段详解

转载自:https://www.sohu.com/a/320177323_505901 /etc/passwd文件: 系统用户配置文件,存储了系统中所有用户的基本信息,并且所有用户都可以对此文件执行读(r)操作。 查看文件内容: /etc/passwd文件内容非常规律,每行记录对应一个用户。 每行用

云原生背景下如何配置 JVM 内存

背景 前段时间业务研发反馈说是他的应用内存使用率很高,导致频繁的重启,让我排查下是怎么回事; 在这之前我也没怎么在意过这个问题,正好这次排查分析的过程做一个记录。 首先我查看了监控面板里的 Pod 监控: 发现确实是快满了,而此时去查看应用的 JVM 占用情况却只有30%左右;说明并不是应用内存满了

在Winform分页控件中集成保存用户列表显示字段及宽度调整设置

在Winform的分页控件里面,我们提供了很多丰富的功能,如常规分页,中文转义、导出Excel、导出PDF等,基于DevExpress的样式的分页控件,我们在其上面做了不少封装,以便更好的使用,其中就包括集成保存用户列表显示字段及宽度调整设置。本篇随笔介绍这个实现的过程,通过在当前程序中序列化方式存储一个记录用户设置的文件,提供介质的存储和加载处理。