1. 首页
  2. >
  3. 数据库技术
  4. >
  5. MySQL

项目重启数据库连接数突增!连接数据库超时!请收下这个方子

结论:

数据库连接数突增是数据库连接资源没有及时释放。

连接数据库超时是因为数据库连接资源释放得过早。

现象1:每次上线项目DB的连接数会突增。

项目重启数据库连接数突增!连接数据库超时!请收下这个方子

原因:是项目关闭的时候没有释放连接资源导致。

DB的connection资源没有正常释放,导致项目启动的时候再次创建数据库连接资源,就出现了连接数突增的现象。一段时间后mysql根据wait_time的配置,自动回收conncetion,所以连接数又回落回来。

如果是是DB的connection资源没有正常释放,最可能的是在项目关闭的时候没有释放掉DB的连接资源。

经过在查看线上jekins的上线脚本后,发现线上停止项目使用的kill进程的方式来停止项目。那么就证明假设都成立了。接下来解决问题环节(程序员们喜闻乐见的百度和谷歌环节了)。

如何释放DB的连接资源,我列举了一下可选方案。

1.主动释放

项目关闭使用正确的stop命令,保证项目能正确的释放掉各种资源。执行命令:xxxx_tomcat.stop

2.被动释放

如下两个配置搭配服用效果最佳 1.JDBC探活:每隔一段时间唤醒连接,保持长连接。 <property name="preferredTestQuery" value="SELECT 1"/>  <property name="idleConnectionTestPeriod" value="300"/> 2.减少连接池内连接生存周期:     2.1 使之小于mysql设置中的wait_timeout的值**很重要**     2.2 大于配置的探活的周期     2.3 小于新项目上线的耗时,就可以在新项目上线过程中mysql自己回收连接资源避免连接突增的现象的发生。 <property name="maxIdleTime" value="1800" />    主要目的是尽可能的在新项目上线的同时,mysql自己就回收了连接资源。

现象2:连接数据库超时。

com.mysql.jdbc.CommunicationsException: The last packet successfully received from the server was58129 seconds ago.The last packet sent successfully to the server was 58129 seconds ago, which is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. mysql

问题原因 :连接池里的connection资源被mysql主动提前释放导致。

原因是在datasource连接池中配置的最大空闲时间到达之前(比如maxIdleTime,不同数据源配置名不一样),已经到达mysql的wait_timeout(最大空闲时间),是mysql主动把connection资源回收。但是项目中的连接池还持有connection,所以当项目中使用connection的时候会报CommunicationsException错误。

解决方案

1.修改mysql的wait_time,interactive_timeout把值调大(不建议如果太大,可能导致连接数较多,引起性能下降)

修改配置my.inf文件  或者  mysql命令set global interactive_timeout = 28800;set global interactive_timeout = 28800;

2.配置JDBC的重连机制autoReconnect(不建议,只有4.x版本,起作用)

jdbc:mysql://localhost:3306/test?user=root&password=&autoReconnect=true

3.减少连接池内的存活时间+JDBC探活(建议,搭配使用效果好)

1.JDBC探活:每隔一段时间唤醒连接,从而保持长连接   <property name="preferredTestQuery" value="SELECT 1"/>    <property name="idleConnectionTestPeriod" value="300"/>  2.JDBC减少连接池内连接生存周期,**小于mysql配置wait_timeout 的值(很重要)***   <property name="maxIdleTime" value="1800" />   

最大闲置资源时间的配置

两个现象的解决方案都指向了同一个配置就是connection的最大闲置资源时间。

项目重启数据库连接数突增!连接数据库超时!请收下这个方子

有两个地方可以配置最大闲置资源时间:

1.在项目的连接池中配置,比如maxIdleTime。

2.在mysql中也可以配置,interactive_timeout和wait_timeout。


三、MySql中的connection超时配置

mysql的配置中有interactive_timeout和wait_timeout两个参数,这两个参数有时候还存在覆盖的关系,所以还是给大伙说清楚一点两个的区别和联系方便大家理解。

建议interactive_timeout和wait_timeout参数值配置成一样的。

1.interactive_timeout和wait_timeout概念

项目重启数据库连接数突增!连接数据库超时!请收下这个方子

2.修改配置参数的方式

1.修改配置文件my.ini

[mysqld] wait_timeout = 20interactive_timeout = 20

2.执行mysql命令

#修改global级别的配置 set global interactive_timeout = 10; set global wait_timeout = 10; #修改session级别的配置 set session  interactive_timeout=20; set session  wait_timeout=20;

3.查看参数配置


项目重启数据库连接数突增!连接数据库超时!请收下这个方子

3.参数不同的继承关系

1.interactive_timeout和wait_timeout配置最终生效都是作用在session交互的时候生效。

2.控制最大空闲时间的参数是wait_timeout在起作用。不管是非交互式还是交互式连接,都是wait_timeout起作用

3.交互式连接下的wait_timeout和interactive_timeout配置都会继承自全局的interactive_timeout参数。


项目重启数据库连接数突增!连接数据库超时!请收下这个方子

1.wait_timeout决定连接超时时间的演示

因为我们是用mysql客户端连接,应该是交互式连接,连接超时起作用的应该是interactive_timeout参数,但是真是的这样吗。


项目重启数据库连接数突增!连接数据库超时!请收下这个方子


2.interactive_timeout不同的继承演示


项目重启数据库连接数突增!连接数据库超时!请收下这个方子


新开一个窗口(交互式连接)查看,wait_timeout 和 interactive_timeout 都继承自global的interactive_timeout


项目重启数据库连接数突增!连接数据库超时!请收下这个方子


使用JDBC查询(非交互式)查看,wait_timeout继承自全局wait_timeout,interactive_timeout继承自全局interactive_timeout


项目重启数据库连接数突增!连接数据库超时!请收下这个方子