02-Oracle连接池配置实战

02-Oracle连接池配置实战 Oracle连接池配置实战——社保系统从20连接到200连接的血泪史连接池不是设个数字就完了。20个连接够用的系统接了更多下游后突然全线超时。这篇文章从社保系统的真实案例出发拆开HikariCP连接池的配置策略——不是调参数是找根因。文章目录Oracle连接池配置实战——社保系统从20连接到200连接的血泪史一、从20到200——不是放大就管用二、HikariCP 核心参数三、连接泄漏——最隐蔽的问题四、连接池太大也不行——数据库侧撑不住五、连接有效性校验——别每次借出都查六、最终配置一、从20到200——不是放大就管用社保系统最初使用HikariCP连接池设了20。单体应用几个接口20个连接绰绰有余。后来接了省平台数据交换、银行扣款回调、养老金发放查询——一个接口进来要同时查3-4个下游。高峰期30人同时操作每人触发一个接口每个接口需要2-3个数据库连接——瞬间需要60-90个连接而池子只有20个。结果不是第7个人被拒绝——是所有请求都在队列里等连接。等一个连接释放后面的请求已经超时。前端白屏。二、HikariCP 核心参数spring:datasource:hikari:minimum-idle:10# 最小空闲连接池初始化时就创建maximum-pool-size:50# 最大连接数含空闲使用中idle-timeout:600000# 空闲超时10分钟超过则回收max-lifetime:1800000# 连接最大生存时间30分钟超时强制回收connection-timeout:30000# 等待连接的超时时间30秒validation-timeout:5000# 连接校验超时leak-detection-threshold:60000# 连接泄漏检测60秒未归还则告警关键是理解三个超时的关系连接生命周期: 创建 → 借出(使用中) → 归还(空闲) → 空闲超时回收 | | | | leak-detection idle-timeout | (60s告警) (10min回收) | max-lifetime (30min强制回收)三、连接泄漏——最隐蔽的问题社保系统曾经出现过这样的现象每天早上正常下午变慢第二天又恢复。日志里没有报错JVM内存正常但hikaricp - connection is not available, request timed out after 30000ms间歇性出现。用leak-detection-threshold60000打开后日志开始输出HikariPool-1 - Connection leak detection triggered for connXX, stack trace follows java.lang.Exception: Apparent connection leak detected at com.zaxxer.hikari.HikariDataSource.getConnection at com.browise.service.PersonService.query(PersonService.java:156) ...问题定位到PersonService.query——某个异常分支里try-with-resources没有正确关闭 ResultSet连接被吃掉了但没归还。问题发生频率每天下午高是因为下午查询量大泄漏累积到连接池耗尽。修法所有数据库操作统一走JdbcTemplate或Transactional不在业务代码里手动管理连接。四、连接池太大也不行——数据库侧撑不住把连接池从20调到200后系统确实不超时了——但Oracle数据库开始报ORA-00020: maximum number of processes exceeded。Oracle 的processes参数限制了同时连接的总进程数。默认是150-300。200个HikariCP连接 50个其他应用连接 250刚好超过。改法不是调大连接池——是减少每个请求的连接数// 改前一个请求打开3次连接Connectionc1ds.getConnection();// 查密码Connectionc2ds.getConnection();// 查状态Connectionc3ds.getConnection();// 查权限// 改后一次连接完成所有查询Connectioncds.getConnection();// 查密码、状态、权限全部在同一连接上执行同时调整OracleALTERSYSTEMSETprocesses500SCOPESPFILE;-- 重启生效五、连接有效性校验——别每次借出都查很多教程让配connection-test-query: SELECT 1 FROM DUAL。HikariCP默认不需要这个——它有更高效的isValid()检查。如果一定要配不要配在借出时校验# 正确只在空闲超时回收前校验hikari:keepalive-time:30000# 每30秒心跳保活# 不配 connection-test-query —— 让HikariCP用自己的isValid只有当Oracle配置了防火墙超时断开空闲连接如DCD/死连接检测才需要keepalive-time。平时不用。六、最终配置spring:datasource:hikari:minimum-idle:5maximum-pool-size:40# 并发×每请求连接数加20%余量idle-timeout:300000max-lifetime:600000connection-timeout:10000# 10秒拿不到就报错别让用户等leak-detection-threshold:30000# 30秒未归还告警keepalive-time:60000# 防火墙有超时断开机制时才配核心原则最大连接数不是越大越好——先算并发请求×每请求连接数再加20%先查连接泄漏再调连接池大小——80%的超时是泄漏导致的减少每请求连接数比增大池子更有效——合并查询到同一个Connectionleak-detection-threshold 是必开项——生产环境不开这个等于盲飞✅ 亮点从社保系统真实案例出发从问题现象一路定位到根因连接泄漏用日志输出直接定位到出问题的代码行。扩展方向Druid vs HikariCP对比、PolarDB/OceanBase连接池适配。