连接池配置你真的会吗?

简介: 连接池配置你真的会吗?

连接池配置

连接池提供了许多参数,最重要的就是最大连接数,连接池能使用的连接数达到上限后,新来的请求需要等待其他请求释放连接。


最大连接数不是越大越好:



  • 过大

客户端需耗费过多资源维护连接,且由于服务端对应的是多个客户端,每一个客户端都保持大量连接,会给服务端带来更大压力:不仅是内存压力,若服务端的网络模型是一个TCP连接一个线程,那么几千个连接意味着几千个线程,导致大量线程切换开销


  • 过小

可能因为获取连接的等待时间太长,导致吞吐量低下,甚至超时无法获取连接



模拟压力增大导致数据库连接池打满

如何确认连接池的使用情况?

如何针对性地进行参数优化?


定义一个用户注册方法,通过 @Transactional 注解为方法开启事务。

一个数据库事务对应一个TCP连接,所以500ms都会占用数据库连接:


随后,修改配置文件启用register-mbeans,使Hikari连接池能通过JMX MBean注册连接池相关统计信息,方便观察连接池:

spring.datasource.hikari.register-mbeans=true

启动程序并通过JConsole连接进程后,可以看到默认情况下最大连接数为10:

使用wrk对应用进行压测,可以看到连接数一下子从0到了10,有20个线程在等待获取连接:

不久就出现了无法获取数据库连接的异常,如下所示:

[15:37:56.156] [http-nio-45678-exec-15] [ERROR] [.a.c.c.C.[.[.[/].[dispatcherServlet]:175 ] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataAccessResourceFailureException: unable to obtain isolated JDBC connection; nested exception is org.hibernate.exception.JDBCConnectionException: unable to obtain isolated JDBC connection] with root cause
java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available, request timed out after 30000ms.

从异常信息中可以看到,数据库连接池是HikariPool,解决方式很简单,修改一下配置文件,调整数据库连接池最大连接参数到50即可。


spring.datasource.hikari.maximum-pool-size=50

然后,再观察一下这个参数是否适合当前压力,满足需求的同时也不占用过多资源。从监控来看这个调整是合理的,有一半的富余资源,再也没有线程需要等待连接了:


在这个Demo里,我知道压测大概能对应使用25左右的并发连接,所以直接把连接池最大连接设置为了50。在真实情况下,只要数据库可以承受,你可以选择在遇到连接超限的时候先设置一个足够大的连接数,然后观察最终应用的并发,再按照实际并发数留出一半的余量来设置最终的最大连接。


其实,看到错误日志后再调整已经有点儿晚了。更合适的做法是,对类似数据库连接池的重要资源进行持续检测,并设置一半的使用量作为报警阈值,出现预警后及时扩容。


在这里我是为了演示,才通过JConsole查看参数配置后的效果,生产上需要把相关数据对接到指标监控体系中持续监测。


这里要强调的是,修改配置参数务必验证是否生效,并且在监控系统中确认参数是否生效、是否合理。之所以要“强调”,是因为这里有坑。


我之前就遇到过这样一个事故。应用准备针对大促活动进行扩容,把数据库配置文件中Druid连接池最大连接数maxActive从50提高到了100,修改后并没有通过监控验证,结果大促当天应用因为连接池连接数不够爆了。


排查发现,当时修改的连接数并未生效。应用虽然使用的Druid连接池,但后来公司的框架组通知组件又要升级了,把连接池替换为Hikari,原来那些配置都无效了,修改后的参数配置当然也不会生效。

连接池所做的调参,一定要亲自验证了,明确修改内容!


目录
相关文章
|
druid Java 数据库连接
什么是连接池?为什么需要连接池呢?连接池的组成原理又是什么呢?
什么是连接池?为什么需要连接池呢?连接池的组成原理又是什么呢?
487 0
什么是连接池?为什么需要连接池呢?连接池的组成原理又是什么呢?
|
6月前
|
SQL Java 数据库连接
自定义HikariCP连接池
自定义HikariCP连接池
283 0
|
3月前
|
监控 druid Java
数据库链接池HikariCP、Druid
数据库链接池HikariCP、Druid
|
7月前
|
SQL 缓存 关系型数据库
连接池设置
连接池设置
65 0
|
druid Java 关系型数据库
Druid连接池的基本配置与使用
Druid连接池的基本配置与使用
3065 0
Druid连接池的基本配置与使用
|
10月前
|
监控 Java 数据库连接
c3p0连接池
c3p0连接池
97 0
|
10月前
|
监控 Java 数据库连接
HikariCP连接池
HikariCP连接池
89 0
连接池问题
连接池问题
131 0
|
XML druid Java
C3P0连接池的基本配置与使用
C3P0连接池的基本配置与使用
513 0
C3P0连接池的基本配置与使用
|
Java 数据库连接 API
自定义数据库连接池
自定义数据库连接池
86 0
自定义数据库连接池