最近公司用的 Mysql 数据库,因为有很多项目使用,偶尔 Mysql 扛不住了,发现有很多没有释放的链接。
查了各种原因。总结下。
业务代码方面:
- SQL 有大量的
select * from table
。 - 有查询单表业务和多表关联查询共用sql语句。
- 有业务查询 SQL 可以批量操作,然后用的循环单条去执行。
- 。。。。N多看不过去的业务处理。有的问题看就痛心。
数据库方面:
- 各种数据库表超大。没有分表等处理措施,导致查询过慢,整体查询性能降低。
- 读写分离没有做。
N
多系统共用一套 mysql 。- 复杂业务查询,大数据异步业务处理绑定到业务数据库上,拖慢性能。
- 。。。。
连接池配置方面:
这个我要说道说道,如果你从网上,不管是百度,还是其他的,甚至Google ( 当然一部分同学用不了 )。都很难找到比较全,或者有详细说明的。不是说没有,是很难。
我用的是阿里巴巴的 Druid 。
原来的配置。
#系统各种DB、缓存配置
#bendi----------
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.0.37:3306/project_demo?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=xxxx
jdbc.validationQuery=SELECT 'x'
jdbc.initialSize=5
jdbc.maxActive=20
jdbc.maxIdle=20
jdbc.minIdle=0
jdbc.maxWait=60000
jdbc.testOnBorrow=false
jdbc.testOnReturn=false
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.minEvictableIdleTimeMillis=25200000
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=1800
jdbc.logAbandoned=true
#redis
redis.ip=192.168.0.28
redis.host=6379
redis.maxActive=200
redis.maxIdle=100
redis.minIdle=5
redis.maxWait=5000
redis.testOnBorrow=true
redis.testOnReturn=true
#es
es.ip=192.168.0.37
es.tcp.port=9301
es.http.port=9201
es.domain=http://manager.vinux.com
#集群名称要和安装保持一致,否则控制台不断打印日志
es.cluster.name=manager
#admin
es.shield.user=manager:manager
#power_user
#es.shield.user=tong:tongchuanwei
#mq
mq.ip=192.168.0.37
mq.name=tong
mq.pswd=tong
mq.scope=/
mq.next.ip=192.168.0.37
mq.next.name=tong
mq.next.pswd=tong
mq.next.scope=/
请同学只看JDBC部分。
大家不知道看没看出来问题。。
jdbc.minEvictableIdleTimeMillis=25200000
这个有很大问题。25200000/1000/60/60 = 7个小时。
啊哦。我不知道这个配置的来源。。。但绝B这有问题。
这是我调整后的JDBC数据源配置,带注释的。
#Driver
jdbc.driverClassName=com.mysql.jdbc.Driver
#数据库链接,
jdbc.url=jdbc:mysql://192.168.0.37:3306/project_demo?useUnicode=true&characterEncoding=UTF-8
#帐号
jdbc.username=root
#密码
jdbc.password=xxxx
#检测数据库链接是否有效,必须配置
jdbc.validationQuery=SELECT 'x'
#初始连接数
jdbc.initialSize=3
#最大连接池数量
jdbc.maxActive=10
#去掉,配置文件对应去掉
#jdbc.maxIdle=20
#配置0,当线程池数量不足,自动补充。
jdbc.minIdle=0
#获取链接超时时间为1分钟,单位为毫秒。
jdbc.maxWait=60000
#获取链接的时候,不校验是否可用,开启会有损性能。
jdbc.testOnBorrow=false
#归还链接到连接池的时候校验链接是否可用。
jdbc.testOnReturn=false
#此项配置为true即可,不影响性能,并且保证安全性。意义为:申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
jdbc.testWhileIdle=true
#1.Destroy线程会检测连接的间隔时间
#2.testWhileIdle的判断依据
jdbc.timeBetweenEvictionRunsMillis=60000
#一个链接生存的时间(之前的值:25200000,这个时间有点BT,这个结果不知道是怎么来的,换算后的结果是:25200000/1000/60/60 = 7个小时)
jdbc.minEvictableIdleTimeMillis=300000
#链接使用超过时间限制是否回收
jdbc.removeAbandoned=true
#超过时间限制时间(单位秒),目前为5分钟,如果有业务处理时间超过5分钟,可以适当调整。
jdbc.removeAbandonedTimeout=300
#链接回收的时候控制台打印信息,测试环境可以加上true,线上环境false。会影响性能。
jdbc.logAbandoned=false
这周做整体配置更新处理。以观后效。
常用数据库validationQuery检查语句
数据库 | validationQuery |
Oracle | select 1 from dual |
mysql | select 1 |
DB2 | select 1 from sysibm.sysdummy1 |
microsoft sql | select 1 |
hsqldb | select 1 from INFORMATION_SCHEMA.SYSTEM_USERS |
postgresql | select version() |
ingres | select 1 |
derby | select 1 |
H2 | select 1 |
#ps 也可以自己定义一个表数据较少,简单的查询也可以。