背景
我们自己平台的产品发现指定的mysql数据库后台发现连接非常多,过多的连接对于数据库是一种负担。这些连接完成SQL执行任务后空闲着啥事也不干,白白占用内存资源,如果这些连接堆积起来,将导致MySQL超过最大连接数,从而无法新建MySQL连接,有可能导致“Too many connections”的错误。
解决
1、
一反馈连接多,我第一件事是查看mysql现在到底有多少连接。
SELECT count(*) FROM information_schema.PROCESSLIST WHERE DB = 'bcloud_dev001'
去查看到底bcloud_dev001这个数据库占用了多少连接。 一看竟然有1030个连接。
然后我第一猜想会不会有连接泄露的情况呢? 然后我参考了这篇文章了解了下 information_schema.PROCESSLIST 这个表的参数 https://zhuanlan.zhihu.com/p/30743094(具体细节不讲)
然后我按照表中的TIME 字段进行排序
SELECT * FROM information_schema.PROCESSLIST WHERE DB = 'bcloud_test001' ORDER BY TIME desc limit 50
如图所示,发现应该不是存在泄露以及别的情况,因为数据TIME大值的很少,而且都是在sleep状态 (sleep状态就是等待客户端向它发送执行语句的状态)。(如果泄露的话,连接没有关闭,那么连接 会一直存在下去。而且会出现大量的长期存在的联接。当然了 这个要结合这连接池的配置一起看,初始化连接与当前连接个数比较)
2、
然后我转手去找springboot中关于连接池的配置。springboot默认的连接池是hikari连接池,这一块不细讲,会另开一篇文章讲解。
找到配置以后发现还是竟然最小的连接数的值没有设置,最大的设置到了1024。那么问题其实就解决了,
官网中对于最小值的配置解释为
🔢minimumIdle
This property controls the minimum number of idle connections that HikariCP tries to maintain in the pool. If the idle connections dip below this value and total connections in the pool are less than maximumPoolSize, HikariCP will make a best effort to add additional connections quickly and efficiently. However, for maximum performance and responsiveness to spike demands, we recommend not setting this value and instead allowing HikariCP to act as a fixed size connection pool. Default: same as maximumPoolSize
它的默认值为 maximumPoolSize 一样,所以相当于初始化的时候就相当于启动了一个最大值的参数的连接池。
后续自己更改了配置
#指定连接池初始化连接数
spring.datasource.minimum-idle=20
#指定连接池最大的连接数,包括使用中的和空闲的连接
spring.datasource.maximum-pool-size=500
别的配置我也都反复看了,我觉得默认值就好。官网建议这里设置一个固定的连接池最好。但是这里我将最大值设置成了500,其实只是不想背锅。项目比较大,啥人写的代码都有,万一泄露了都是个问题。
多说下 wait-timeout
mysql的wait-timeout 这个配置针对jdbc连接mysql的情况。如果在mysql中有大量的sleep的连接,那么设置这个参数就显得很有必要。它的作用是在设定的时间内关闭sleep的连接。默认值28800(8个小时)
查看wait-timeout的值
show global variables like 'wait_timeout';
修改wait-timeout的值(将wait_timeout的值修改为30s)
set GLOBAL wait_timeout=30
这样相当于是设置了全局变量,但是如果重启mysql服务的话,这个值又会被初始化。如果想永久的变动此值的话,要在my.cnf的修改此值的大小。
网友评论