我有一个用grails构建的web服务,它连接到MySQL数据库。自从我升级到2.4.3后,我遇到连接池没有释放连接的问题,导致异常:
org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-bio-8080-exec-216] Timeout: Pool empty. Unable to fetch a connection in 30 seconds, none available[size:50; busy:50; idle:0; lastwait:30000]
这是我的Datasources.groovy
dataSource {
url = "jdbc:mysql://..."
username = "xxx"
password = "xxx"
pooled = true
properties {
maxActive = 50
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
dataSource_survey {
url = "jdbc:mysql://..."
username = "xxx"
password = "xxx"
pooled = true
properties {
maxActive = 50
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
我读过Grails JIRA,有些人似乎有类似的问题。但我无法使用那里提供的信息来修复它。
访问连接池的状态将有助于调试很多。如何检查连接池的状态以查看运行期间有多少连接空闲/忙碌?
答案 0 :(得分:6)
连接池注册为javax.sql.DataSource
,但该接口只有获取Connection
的方法(一个用户名/密码,一个没有),访问日志编写器,获取/设置登录超时。其他所有内容由供应商决定,供应商最初在配置池的方法中,以及在整个应用程序运行中使用和监控它们之间的共性很少。
因此,您确实需要找出用于池的库并使用它们的API。那理想情况下就像访问dataSource
bean一样简单(只是依赖 - 将它注入到服务/控制器等中,就像任何bean一样 - 作为类范围字段,在这种情况下def dataSource
)并打印其类名。但是我们将数据源包装在几个代理中以添加一些重要的行为,因此不容易访问
你很幸运 - 对于这样的情况,我们单独留下原始的未经处理的实例并将其注册为dataSourceUnproxied
bean,你也可以依赖注入(只是不能访问)任何连接,只有信息)。
很长一段时间我们使用commons-pool来管理数据源,但不久前我们切换到Tomcat JDBC Pool,因为基准测试显示它比他们看到的任何其他更快(包括C3P0) ,它的配置方法基于commons-pool,因此它基本上是一种替代方案,具有显着的性能提升和更多的可配置性。