假设设置了最小和最大的连接为10,20,那么应用一旦启动则首先打开10个数据库连接,但注意此时数据库连接池的正在使用数字为0--因为你并没有使用这些连接,而空闲的数量则是10。然后你开始登录,假设登录代码使用了一个连接进行查询,那么此时数据库连接池的正在使用数字为1、空闲数为9,这并不需要从数据库打开连接--因为连接池已经准备好了10个给你留着呢。登录结束了,当前连接池的连接数量是多少?当然是0,因为那个连接随着事务的结束已经返还给连接池了。然后同时有11个人在同一秒进行登录,会发生什么:连接池从数据库新申请(打开)了一个连接,连同另外的10个一并送出,这个瞬间连接池的使用数是11个,不过没关系正常情况下过一会儿又会变成0。如果同时有21个人登录呢?那第21个人就只能等前面的某个人登录完毕后释放连接给他。这时连接池开启了20个数据库连接--虽然很可能正在使用数量的已经降为0,那么20个连接会一直保持吗?当然不,连接池会在一定时间内关闭一定量的连接还给数据库,在这个例子里数字是20-10=10,因为只需要保持最小连接数就好了,而这个时间周期也是连接池里配置的。
dbcp可能是使用最多的开源连接池,原因大概是因为配置方便,而且很多开源和tomcat应用例子都是使用的这个连接池吧。这个连接池可以设置最大和最小连接,连接等 待时间等,基本功能都有。该数据连接池主要使用在spring当中整合的数据连接池:
< bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" >
< property name = "driverClassName" value = "com.mysql.jdbc.Driver" />
< property name = "url" value = "jdbc:mysql://127.0.0.1/test" />
< property name = "username" value = "root" />
< property name = "password" value = "root" />
</ bean >
使用评价:在具体项目应用中,发现此连接池的持续运行的稳定性还是可以,不过速度稍慢,在大并发量的压力下稳定性有所下降,此外不提供连接池监控。class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass"
value="com.mysql.jdbc.Driver">
</property>
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/ test?useUnicode=true&characterEncoding=utf-8">
</property>
<property name="user" value="root"/>
<property name="password" value="root "/>
<!--连接池中保留的最大连接数。Default: 15 -->
<property name="maxPoolSize" value="20"/>
<!--连接池中保留的最小连接数。-->
<property name="minPoolSize" value="2"/>
<!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
<property name="initialPoolSize">
<value>10</value>
</property>
<!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
<property name="maxIdleTime" value="60"/>
<!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="idleConnectionTestPeriod" value="60"></property>
<!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
<property name="acquireIncrement">
<value>5</value>
</property>
</bean>
proxool这个连接池可能用到的人比较少,但也有一定知名度,这个连接池可以设置最大和最小连接,连接等待时间等,基本功能都有。
但是proxool有一个优势--连接池监控,这是个很诱人的东西,大概的配置方式就是在web.xml中添加如下定义:
<servlet>
<servlet-name>admin</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>admin</servlet-name>
<url-pattern>/admin</url-pattern>
</servlet-mapping>
在另外2个开源连接池中成功结束,但在proxool中出现异常退出。
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
<init-param>
<param-name>allow</param-name>
<param-value>127.0.0.1</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
Druid的简介
Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
同时Druid不仅仅是一个数据库连接池,它包括四个部分:
Druid是一个JDBC组件,它包括三个部分:
基于Filter-Chain模式的插件体系。
DruidDataSource 高效可管理的数据库连接池。
SQLParser
Druid的功能
1、替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
2、可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
3、数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
4、SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
5、扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
使用springmvc+mybatis+druid时需要注意增加如下包不然容易报错
其配置如下在spring_mybatis.xml当中
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 数据库连接名 -->
<property name="url" value="${url}"/>
<!-- 数据库用户名 -->
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<!-- 数据使用的链接驱动 -->
<property name="driverClassName" value="${driver}"/>
<!-- 初始化时建立物理连接的个数 ,最小,最大-->
<property name="initialSize" value="${initialSize}"/>
<property name="minIdle" value="${maxIdle}" />
<property name="maxActive" value="${maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${maxWait}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />
<!-- 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效 -->
<property name="testWhileIdle" value="true" />
<!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
<!-- 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->
<property name="testOnBorrow" value="true" />
<!-- 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 -->
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<!-- 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大同时需要配置,比如说oracle。在mysql下建议关闭。
<property name="poolPreparedStatements" value="false" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
-->
<!-- 调用时的时间超过了1800ms之后直接关掉该链接 连接池为了防止程序从池里取得连接后忘记归还的情况, 而提供了一些参数来设置一个租期, 使用这个可以在一定程度上防止连接泄漏
<property name="removeAbandoned" value="true" />
<property name="removeAbandonedTimeout" value="1800" />
-->
<!-- 配置监控统计拦截的filters 主要用来监控sql的执行状态时间以及反映时间-->
<property name="filters" value="stat" />
</bean>
在web.xml当中配置文件配置监控:
<!-- 监控配置 -->
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
总结:
综上所述,这几种开源连接池各有优劣,推荐使用druid,经检验这种连接池性能稳定,承压能力强。由于它具备监控功能,因此在开发测试时使用,有助于确定是否有连接没有被关掉,可以排除一些代码的性能问题。通过druid的监控sql数据的执行可以一定程度帮助开发提前发现并且优化数据库。