最近公司的某个程序发生假死( java ,springboot ),导出 dump 文件后,发现 tomcat 的 200 个线程全卡在了 getConnecton()获取数据库连接上。 然后查了一下数据库的空闲连接数大概有 5000 ,没有达到 oracle 的 10000 个上限,但是其它的程序也有获取连接慢的情况。但是我的程序就卡死在获取连接上,为什么我的连接池没有返回连接呢??

并且 6 个节点全部从 eureka 掉线,迟迟获取不到连接

那是库理论支持的链接吧,你的硬件能跑这么多。照你的说法你程序已经连了 5000 个(一两百我都感觉多),我这半吊子理解是你应该排查你程序为啥链接没释放掉,网络,慢 sql ,大批量导出等,还有个影响可能是其他库的事例影响。

应该是其它程序实例占用了太多链接,但是不知道为什么我的程序实例一直没释放池子里的连接给别的线程用导致程序假死

你这我也遇到过 不过选择重启 springboot 就恢复了也是奇怪

服务器那边的 端口限制 看了没得

能访问到,但是 springboot 默认的 tomcat 线程池的 200 个线程都占满了,新的请求只能在那等待着了

正常一个程序能有两百连接数就已经非常够用了,你不妨把你的程序的数据库连接池配置发上来让大家看看是不是不合理,tomcat 线程池和数据库线程池不是一个东西

hikari 的 connectionTimeout 有没有配置

我感觉就是你的线程池的连接没有释放导致的吗,不要在事务里面做耗时操作,特别是慢的 http 接口,会导致连接不会放回池子里面,所以导致获取连接超时,不是数据库的问题而是代码问题。

我只是说 tomcat 的线程池都被 getConnection 卡住了

用的是 dbcp2 ,waitTime 默认值是-1 ,无限等

我获取连接超时时间当时没设置,使得是默认值,等待无限长

目前的解决方案就是换连接池,以及别的服务不要开太多的连接数

用 datagrip 了没有 这个很猛,之前开发库提示连接数不够,查了下我一个 ip 就占了两百个链接

没有

另外发现一个东西,seata (分布式事务框架)在请求结束后会 release 连接,而正常请求中的连接会 return 回数据库连接池

不如配置发上来一起看看

一般都建议 fastfail,偶尔一个报错总比整体持掉好

遇到过,连接池配置问题,贴下配置

动态数据源,就配置了个数据源类是 dbcp2 ,公司的动态数据源框架(然后没有配置连接池,用的默认的)

理论上应该设置一个 pod 的 max-connections.
然后数据库的 active connection/max connection/idle connection/query time 等等这些指标都应该作为监控来作为调整配置的决策因素。
引申开来包括程序线程池的使用情况。
起个项目来优化这些吧。然后推广到公司。credit 不来了吗。

设置一个超时时间把,一直等也太傻了

没有合适的值,如果小了就扩大一倍,直到扩到不卡
当然扩大很多之后依然卡,问题应该不在数据库连接上

遇到过类似的,是超时时间的问题,顺便再解决下慢 SQL 。不然还早还会碰到。

用的什么连接池?楼上说的有道理,慢 sql 导致连接未释放,同一个 tomcat 线程配置了最大连接池数量,到了最大连接数数会阻塞获取连接池。1.排查慢 sql 。2.修改连接超时时间

多大配置的数据库啊。。设置了 10000 个连接数