Spring Boot Admin健康检查引起的Spring Boot服务假死

问题现象

最近在spring boot项目中引入了 spring-boot-starter-actuator 后,测试环境开始出现服务假死的现象,

且这个问题十分怪异,只在多个微服务中的简称A的这个服务中出现,其他服务都没有出现这个问题,

之所以说他是假死,是因为只是http请求无法访问进去了,但是该服务的定时任务却可以定时执行。

问题排查

通过查看jvm的线程信息发现,假死的A服务中,存在很多目前正在waiting状态的http nio线程,

进一步跟踪这些线程的堆栈信息,发现他们都在Alibaba Druid连接池的获取Connection方法中等待获取到最新的Connection,

第一反应是不是连接泄露了,存在慢sql、阻塞住的sql,或者手动获取connection但是没有归还的现象,

于是通过在定时任务代码中打印连接池的状态,发现也没有这种情况,而且连接池的最大连接数设置的也挺大的。

初步定位

通过观察该连接池的链接对象,发现是一个sql server数据库,但是我们的项目配置连接的其实是mysql,

在代码中搜索发现了有一个手动创建连接池的地方,而这里是为了与一个客户的sql server数据库做同步使用的,但是在给其他的客户部署时,并不需要这个操作,代码如下:

这里的操作有一个最大的问题,就是当不设置Druid连接池的等待连接时间时,该时间是-1,即默认永远等待,永不超时

最终定位

有了上面的代码,则需要确认为什么获取不到connection?造成永远等待?

这很正常,因为其他的客户环境并没有sql server,完全无法连接上啊,这时候Druid连接池中的可用connection压根没有,

然后spring boot admin,又不停的通过http轮询检查服务健康状态,最终它的每次http请求都会陷入阻塞等待connection,加之http又没有设置连接超时时间,

最终健康检查http连接占满了服务的http连接,导致其他的请求无法进入。

解决与避免

这里存在几个问题

  1. 该代码应当在指定客户环境运行,其余客户不应当创建该连接池
  2. 连接池配置应当通过yml文件配置,这样可以尽快的发现系统中存在的相关io组件,并发现其配置的不正确性,spring boot支持多数据源配置。
相关推荐
葫芦和十三4 小时前
图解 MongoDB 05|文档模型设计:内嵌 vs 引用,反范式不是免费午餐
后端·mongodb·agent
不能放弃治疗7 小时前
单 Agent 实现模式
后端
IT_陈寒9 小时前
Redis内存爆了,原来我漏掉了这个致命配置
前端·人工智能·后端
小bo波10 小时前
从"任意文件复制"深挖Java I/O:字符流与字节流的本质抉择
java·nio·io流·后端开发·文件复制
fliter10 小时前
最后一块拼图:用 bitvec 构造 IPv4 包,真正做出自己的 Ping
后端
用户35218024547511 小时前
🎆从 Prompt 到 Skill:让 Spring AI Agent 学会"装新技能"
人工智能·spring boot·ai编程
fliter11 小时前
用 Rust 解析并生成 ICMP 包:checksum、nom 与 cookie-factory
后端
蝎子莱莱爱打怪11 小时前
XZLL-IM干货系列 03|消息 ID 设计:一个 UUID 搞不定的事,我用两个 ID 解决了
后端·面试·开源
fliter11 小时前
从 panic 到 Result:用 Rust 重新整理一个 ping 项目的错误处理
后端
森蓝情丶12 小时前
我给 AI 搭了个法庭:一个前端仔的 LangGraph 实战全记录
前端·后端