数据库连接池:为什么你的应用一启动就占500MB内存
很多人发现自己的Java应用启动就吃掉500MB内存,排查半天发现是数据库连接池配的。连接池不是越大越好,配错了反而拖垮数据库。
为什么需要连接池
每次执行SQL都要经历:TCP三次握手→MySQL认证→执行查询→关闭连接。一套流程下来光建立连接就要3-5毫秒。如果每个请求都新建连接,高并发下数据库光处理连接请求就忙不过来了。连接池的思路是提前建好一批连接放在那里,请求来了直接取一个用,用完还回去,省掉了反复建连接的开销。
连接池的三个核心参数
minimumIdle(最小空闲连接数):池子里至少保留几个空闲连接。设太小请求来了要等新建连接,设太大浪费内存。HikariCP默认10个。maximumPoolSize(最大连接数):池子最多能有多少个连接。这是最关键的参数,设太大数据库扛不住,设太小请求排队。通常建议公式:最大连接数 = CPU核心数 * 2 + 磁盘数。connectionTimeout(获取连接超时时间):等多久拿不到连接就报错。默认30秒,太长用户等不了,太短容易误报。
HikariCP为什么快
SpringBoot 2.x默认的连接池从Tomcat JDBC换成了HikariCP,性能提升明显。HikariCP快的原因:用ConcurrentBag替代了传统的BlockingQueue,减少锁竞争;用Javassist字节码生成代理对象而不是用JDK动态代理;精简了代码量,整个jar包才130KB。实测下来,HikariCP的获取连接延迟比Tomcat JDBC低一个数量级。
常见配置错误
把最大连接数设成100甚至200,以为连接越多越快。实际上MySQL默认max_connections才151,你一个应用就占了100个,其他服务全连不上。而且连接太多会导致MySQL线程上下文切换频繁,性能反而下降。另一个错误是不设连接超时时间,连接池满了之后请求一直等,线程被阻塞,最终导致整个应用卡死。
怎么排查连接池问题
HikariCP自带监控,开启metrics后可以看到:活跃连接数、空闲连接数、等待获取连接的线程数、连接使用时长。如果活跃连接数长期等于最大连接数,说明连接池太小或者有慢查询占用连接。如果等待线程数持续增长,说明连接池已经满了,请求在排队。SpringBoot可以通过actuator的/actuator/metrics/hikaricp接口直接看到这些指标。




提供云计算服务