赞
踩
基本上来说,大部分项目都需要与数据库交互,而要与数据库交互的话,就不得不提数据库连接池。市面上的连接池也有很多,今天我们主要讲一讲阿里的数据库连接池druid。
初始化连接
initialSize: 50
# 最大活动连接数
maxActive: 100
maxPoolPreparedStatementPerConnectionSize: 50
# 最大超时等待时间,单位毫秒
maxWait: 60000
# 配置一个连接在池中最小生存的时间(当前时间-最后活动时间),单位是毫秒
minEvictableIdleTimeMillis: 300000
maxEvictableIdleTimeMillis: 900000
# 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,
minIdle: 10
# 打开PSCache,并且指定每个连接上PSCache的大小
poolPreparedStatements: true
#标记是否删除泄露的连接,如果空闲时间超过removeAbandonedTimeout则删除
removeAbandoned: true
#关闭abanded连接时输出错误日志
logAbandoned: false
#超时时间;单位为秒。空闲时间(当前时间-连接时间)超过这个时间被删除
removeAbandonedTimeout: 1200
#检测取出连接池的连接是否可用,会影响性能
testOnBorrow: false
#指明是否在归还到池中前进行检验
testOnReturn: false
#建议配置为true,不影响性能,并且保证安全性。如果testOnBorrow=true则此配置无效。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
testWhileIdle: true
#在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位.如果设置为非正数,则不运行空闲连接回收器线程。配合testWhileIdle使用
timeBetweenEvictionRunsMillis: 2000
# 下面为连接池的补充设置,应用到上面所有数据源中
type: com.alibaba.druid.pool.DruidDataSource
#校验的sql
validationQuery: SELECT 1 FROM DUAL
#设置获取连接时的重试次数,-1为不重试
NotFullTimeoutRetryCount: 3
#true表示向数据库请求连接失败后,就算后端数据库恢复正常也不进行重连,客户端对pool的请求都拒绝掉.false表示新的请求都会尝试去数据库请求connection.默认为false
BreakAfterAcquireFailure: false
#设置获取连接出错时的自动重连次数,配合BreakAfterAcquireFailure
ConnectionErrorRetryAttempts: 3
#异步初始化策略
asyncInit: true
1)数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连接;如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个连接,如果这个等待时间超过了maxWait,则会报错;
如果当前正在使用的连接数没有达到maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。
在连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。
2)同时连接池内部有机制判断,如果当前的总的连接数少于miniIdle,则会建立新的空闲连接,以保证连接数得到miniIdle。
如果当前连接池中某个连接在空闲了timeBetweenEvictionRunsMillis时间后仍然没有使用,则被物理性的关闭掉。
有些数据库连接的时候有超时限制(mysql连接在8小时后断开),或者由于网络中断等原因,连接池的连接会出现失效的情况,这时候设置一个testWhileIdle参数为true,可以保证连接池内部定时检测连接的可用性,不可用的连接会被抛弃或者重建,最大情况的保证从连接池中得到的Connection对象是可用的。
当然,为了保证绝对的可用性,你也可以使用testOnBorrow为true(即在获取Connection对象时检测其可用性),不过这样会影响性能。
关于调优,主要是该如何设置连接池大小呢?
可以很直接的说,关于数据库连接池大小的设置,大部分程序员可能都会依靠自己的直觉去设置它的大小。
其实连接数设置多大合适,取决于很多因素,我总结了以下几点可供参考:
假如我们不考虑磁盘和网络的影响,如果一个8核的服务器,那连接数设置为8肯定是最优性能了,因为不需要切换上下文,如果再增加的话,肯定会因为切换上下文而影响性能。
但是数据库在保存数据时,肯定会存储在磁盘上,进而肯定有磁盘IO等待的时间,此时线程处于IO阻塞状态,没啥事干,这时候操作系统可以将空闲的CPU核心用于其他线程。
所以当你的线程处理是IO密集型时,可以让连接数大一些,这样可以在同样的时间内,完成更多的工作。
网络IO跟磁盘IO类似,在以太网读写数据时也会造成阻塞。
基于PostgreSQL基准性能测试,给出了一个连接数的计算公式:
连接数 = ((核心数 * 2) + 有效磁盘数)
核心数不应包含超线程(hyper thread),即使打开了超线程也是如此。
所以,连接池中的连接数量大小应该设置成:数据库能够有效同时进行的查询任务数(通常情况下来说不会高于 2*CPU核心数)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。