合理使用对象池可以大幅减少对象创建、初始化时间,连接池作为对象池的一种典型应用,虽不能减少数据库的物理连接数,但是却大大减少数据库连接的创建、初始化时间。关于数据库连接池的工作原理,这里作一简单说明:
1)初始化一个连接池管理器,DBConnectionPoolManager;
2)获取连接池,ConnectionPool,多个数据库会有多个connectionpools;
2)ConnectionPool负责创建、释放、回收连接;
3)连接池会有Thread在侦听连接是否有效、sql执行时间是否超标等;
Proxool作为一开源连接池,由于其支持多数据库且有强大的监控、统计功能,广受部分开发人员垂青,本人也不例外。
1、proxool何时创建连接,Proxool在下述2种情形下会创建连接:
1)程序显性获取数据库库连接时,比如getConnection时,此时proxool可能会创建连接。当无可用连接时,proxool便会即时创建一个连接,此时该连接状态为Active。
2)PrototyperThrea
当当前连接数小于最小连接数或者当前可用连接数小于最小可用连接数时,便会创建新连接,并将新建的连接状态置为Available.
2、执行sql语句时,proxool在做哪些事情
1)记录正在执行的sql语句;
2)记录开始执行时间,执行结束事件;
3)按不同的事件频率统计,sql语句平均耗时;
4)记录sql执行次数;
3、连接如何回收、销毁
HouseKeeperThread,该thread负责检查连接是否有效、连接sql执行时间是否超过最大activetime(默认5分钟),连接存活时间是否超过最大存活事件(默认4小时).
一个良好的程序员应该在获取数据库连接后及时释放连接,一旦有个别程序数据库连接不会释放,则连接池马上将达到最大连接数,并阻塞之后的所有数据库请求。
1)连接失效,proxool会根据预设的测试sql语句,通常是取数据库时间(select current_date)等,测试该连接是否可以正常工作,如果测试失败,则proxool会从连接池中移除该对象,并销毁;
2)sql执行时间大于maxactivetime
当遇上大数据量select语句,或者update大数据量索引表时,往往会耗时较长,如果一个sql语句其在maxactivetime时间内未执行完毕的话,proxool会将其强行关闭,从pool中移除,并销毁;
3)当连接建立时间到现在超过maxconnectionlife
HouseKeeperThread在run过程中发现,有个available连接其建立到现在已超过maxconnectionlife时,proxool会将其物理关闭,从pool中移除,并销毁,为了确保物理连接数最少。
spring中以dataSource方式使用proxool连接池
(by goodhumor)
方式一:
在Spring的"applicationContext.xml"中的dataSource bean定义——
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="dataSource"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
="org.logicalcobwebs.proxool.ProxoolDataSource"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="driver"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
value
>
com.mysql.jdbc.Driver
</
value
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
property
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="driverUrl"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
value
>
jdbc:mysql://localhost:3306/dbname?user=yourname
&
password=yourpass
</
value
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
property
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="user"
value
="yourname"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="password"
value
="yourpass"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="alias"
value
="Pool_dbname"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="houseKeepingSleepTime"
value
="90000"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="prototypeCount"
value
="0"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="maximumConnectionCount"
value
="50"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="minimumConnectionCount"
value
="2"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="simultaneousBuildThrottle"
value
="50"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="maximumConnectionLifetime"
value
="14400000"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="houseKeepingTestSql"
value
="select CURRENT_DATE"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
bean
>
第一种方式需要把用户名和密码写在连接串里面,
ProxoolDataSource类提供的user,password属性似乎没有什么用。
无论提供什么,它都会以空用户名、密码去连接数据库。
这可能是Proxool RC0.93的一个bug。
不过配置中的user,password两个属性还必须设置,否则hibernate会报空指针错误。
方式二:
在Spring的"applicationContext.xml"中的dataSource bean定义——
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
bean
id
="dataSource"
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
class
="org.springframework.jdbc.datasource.DriverManagerDataSource"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="driverClassName"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
value
>
org.logicalcobwebs.proxool.ProxoolDriver
</
value
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
property
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="url"
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
value
>
proxool.Pool_dbname
</
value
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
property
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
bean
>
第二种方式需要预先在"web.xml"先配置好Proxool连接池,配置如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet-name
>
proxoolServletConfigurator
</
servlet-name
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet-class
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
org.logicalcobwebs.proxool.configuration.ServletConfigurator
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
servlet-class
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
init-param
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
param-name
>
xmlFile
</
param-name
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
param-value
>
WEB-INF/proxool.xml
</
param-value
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
init-param
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
load-on-startup
>
1
</
load-on-startup
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
servlet
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet-name
>
context
</
servlet-name
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
servlet-class
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
org.springframework.web.context.ContextLoaderServlet
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
servlet-class
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
load-on-startup
>
2
</
load-on-startup
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
servlet
>
注意,第二种方式下Spring的上下文加载如果想使用listener方式(Struts2要求),
则与连接池有关的Bean全得延迟初始化。因为listener比servlet优先初始化,
如果相关Bean不是lazy-init的话,则启动服务器时会出现Bean找不到连接定义的异常。
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
其中proxool的配置文件可以采用xmlFile"proxool.xml"或者propertyFile"proxool.properties"
"proxool.xml"格式如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<?
xml version="1.0" encoding="UTF-8"
?>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
proxool-config
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
proxool
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
alias
>
Pool_dbname
</
alias
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
driver-url
>
jdbc:mysql://localhost:3306/dbname
</
driver-url
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
driver-class
>
com.mysql.jdbc.Driver
</
driver-class
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
driver-properties
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="user"
value
="yourname"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
property
name
="password"
value
="yourpass"
/>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
driver-properties
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
house-keeping-sleep-time
>
60000
</
house-keeping-sleep-time
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
maximum-connection-count
>
20
</
maximum-connection-count
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
minimum-connection-count
>
2
</
minimum-connection-count
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
prototype-count
>
0
</
prototype-count
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
simultaneous-build-throttle
>
20
</
simultaneous-build-throttle
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
house-keeping-test-sql
>
select CURRENT_DATE
</
house-keeping-test-sql
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
statistics
>
15s,10m,1d
</
statistics
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
statistics-log-level
>
INFO
</
statistics-log-level
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
proxool
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<
proxool
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<!--
可以配置多个库
-->
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
proxool
>
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
</
proxool-config
>
"proxool.properties"格式如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.alias
=
Pool_dbname
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.driver-url
=
jdbc:mysql://localhost:
3306
/dbname
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.driver-class
=
com.mysql.jdbc.Driver
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.user
=
yourname
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.password
=
yourpass
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.house-keeping-sleep-time
=
60000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.house-keeping-test-sql
=
select CURRENT_DATE
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.maximum-connection-count
=
10
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.minimum-connection-count
=
3
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.maximum-connection-lifetime
=
18000000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.prototype-count
=
3
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.simultaneous-build-throttle
=
10
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.recently-started-threshold
=
60000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.overload-without-refusal-lifetime
=
50000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.maximum-active-time
=
60000
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.verbose
=
true
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.trace
=
true
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
0
.proxool.fatal-sql-exception
=
Fatal error
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
jdbc-
2
.proxool.alias
=
Pool_dbname2
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
……
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
<!--可以配置多个库-->
-----------------------------------------------------------
个人比较倾向于第二种配置方式,
一来可以避免在Spring的"applicationContext.xml"中写一大堆参数,
尤其是避免了driverUrl中带用户名密码(这会显示在proxool包中带的
org.logicalcobwebs.proxool.admin.servlet.AdminServlet输出的页面中)
二来proxool连接池可以在tomcat启动时就初始化好,可以提高第一次访问web时的连接速度。