☰
30 秒等不到连接:锅在拼 Excel 那段代码
2026/10/15 16:58:20 网站建设 项目流程

这条超时,我起初完全盯错了地方。 起因是压测加档:8 路并发直接抬到 32, 成排的红字开始往外蹦:

java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.

我脑补的头号嫌疑人是库倒了。 赶紧登服务器看了眼会话表:

Id User Host db Command Time State Info 142 app_ro 10.18.18.21:52412 order_db Sleep 17 143 app_ro 10.18.18.21:52418 order_db Query 0 executing select id from t_order

拢共十一条会话, 打盹挂 Sleep 闲牌的占大头。 MySQL 那边清闲得很,根本没累着。

服务跑在 Spring Boot 2.1.6 上。 池子相关的配置行,我们一行都没落过笔。 没落笔就意味着全程吃出厂配给, maximum-pool-size 的缺省档位就是 10。

这条红字的真正含义,得掰开讲: 它不是说连不上数据库, 而是应用堵在池子自己的门口领不到号。 伸手要一条连接, 苦等 connection-timeout 那道三十秒的闸门也没人腾位, 它只能自己撒手。 红字出自池子,不关数据库的事。

〈线程池核心线程数和队列长度怎么定,别照抄核数加一〉 里, 我顾着把线程往多了堆, 却从没碰过这十张通行证。 32 条线程在场,能分到账的只有 10 条, 剩下 22 条站门外, 站满 30 秒,吐出来的就是上文那行。

要数数队里杵着几位, 非得翻 Hikari 家的 debug 级日志不可。 说实话,这个开关我是在出了事之后才补开的。

最难咽下的是那 10 条怎么会不够用。 跟查询本身快不快扯不上关系, 病根在有人长时间霸着坑位。

事务只要开着, 一条连接就被整个押到收场。 半路再发一次 RPC, 对面 3 秒不吭声,这 3 秒连接便押在调用方掌心。 更普遍的踩法是 @Transactional 整只扣在方法外头, 方法里光两条 SQL 之外, 还捎带做了不少别的事。

报表导出,是我那阵子扣住坑位的那档活: 数据让 select 取完,紧接着拼 Excel, 十几秒工夫,这条连接别人碰都别想碰。

一番调整落定后,hikari 段落变成:

spring: datasource: hikari: maximum-pool-size: 32 connection-timeout: 10000 max-lifetime: 1200000 leak-detection-threshold: 60000

池子条数按线程的量级去配, 但上限由数据库的饭量说了算。 库侧的 max_connections 统共只有两百, 还有另外四家服务挂着它。

等待闸门由 30 秒压成 10 秒。 让请求干站三十秒再判死, 上游那头的会话早就散伙了, 白搭的二十秒不如省下,趁早给个干脆。

max-lifetime 的雷区在它的取值: 得比 MySQL 那边的 wait_timeout 矮一头。

照默认盘算,wait_timeout 是 28800 秒, max-lifetime 则是 30 分钟, 两者本碰不到一块。

怕只怕某套环境动过数据库那侧的取值,把它调矮了: 数据库那头先掐线,池子这边浑然不觉, 照样把已经死透的连接往外递。

leak-detection-threshold 针对的是借而不还: 取 60000,谁占着连接满一分钟还没还, 日志就把谁拎出来示众。

导出那摊代码,我到现在还没理清爽。 连接真正归池卡在哪个节点, 我原先猜,方法一返回就结了, 更深一层我没往下刨。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询