`
mgoann
  • 浏览: 249877 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Java数据库连接池(二)

阅读更多

 

Java数据库连接池(二)

 

连接池需要解决的问题

         连接池在Java应用中扮演着重要的角色,J2EE已经将连接池作为Java的一项基本规范纳入到JDBC4.0中,可见连接池的重要性。作为所有的连接池都需要面对一些共通的问题,判断或者选择连接池时,就要从这些方面去下手。

 

连接:一个连接池最基本的问题就是需要提供连接。

监控:对连接池提供有效的监控手段,监控要实现动态生效更好,可通过监控对连接使用率、可能泄露的连接、获取连接平均响应时间、获取连接最大响应时间、连接最长归还时间、创建连接总数、物理释放连接数,最好能够根据这些数据再加上时间,形成一些可视化的报表,方便开发人员或者是维护人员对连接池进行优化,以达到在建立过剩的连接情况下最大限度的达到连接重用。

高并发:必须能够应对高并发,保证连接池的稳定性的同时,达到高性能。

数据源:好的连接池应当以一种数据源的形式出现DataSource,这也是连接池的一个规范。

高性能:连接池对于应用来说扮演着重要的角色,同时也会影响到应用的性能。所以构建高性能的连接池至关重要。

缓存:缓存要从多个维度去理解,比如连接缓存、查询结果缓存。只有很好的应用缓存特性才能够构建高性能的连接池。

连接释放:连接释放应当分为两种:一种是对连接的物理释放,也就是真正的断开与数据库的连接,通常需要在关闭连接池前做的事情。一种是对连接的逻辑释放,是指通过该操作将一些用过的连接放回到连接池中。而这里的连接释放方式需要注意,应当通过Connection的close方法来进行操作,这样可以避免改变用户的编程习惯。

池:池的设计对于连接池非常重要,可以说是连接池的核心灵魂,经过认真周密设计的池,可能满足高并发、高性能、高重用性等特点。

连接可用性探测:连接池应当对自身提供给应用的连接负责,提供连接前,必须对连接是否存活,是否可用做检测,将不可用的连接进行物理释放,以免造成应用拿到不可用的连接,导致操作失败。

灵活的配置:通常连接池是需要根据具体的应用场景来进行个性化的配置,以便在任何场景下连接池都可以以最优的方式工作,这需要连接池支持当前比较常见的配置方式,例如:xml、properties、注解。提供丰富的多样的配置方式还不够,最好还要实现配置的动态生效,即不重启应用的情况下,动态使得最新的配置进行工作。

安全性:连接池是需要配置数据库的一些基本信息的,例如:url、password、username等,这些涉及到安全性,至少应当对password进行加密,防止数据库密码泄露。

学习成本:通常情况下,连接池的学习成本是基本相同的,连接池比较的通用。这里所将的学习成本是指要尽量贴近或者是完全按照规范进行实现,这样可以大大减少用户的学习成本,可保持良好的上手性和编程习惯。

集成问题:应当无缝的集成到应用当中,例如:spring、tomcat等。

多数据源:应当提供多数据源的解决方案。

分布式事务:在多数据源的场景下,应当实现分布式事务。

 

连接池的一般实现

几个概念

Connection:是指JDBC规范中的Connection,与接口java.sql.Connection相对应。与特定数据库的连接(会话)。在连接上下文中执行 SQL 语句并返回结果,一个Connection代表一个物理数据库连接。

PhysicalConnection:物理连接,真正完成数据库与应用之间的连接建立和维护,并解析语义,返回相应,一般由各个厂家在驱动程序中提供。例如:Oracle的为oracle.jdbc.driver.PhysicalConnection。

PooledConnection:是与JDBC规范中javax.sql.PooledConnection相对应,为连接池管理提供钩子 (hook) 的对象。PooledConnection 对象表示到数据源的物理连接。该连接在应用程序使用完后可以回收而不用关闭,从而减少了需要建立连接的次数。应用程序员不直接使用 PooledConnection 接口,而是通过一个管理连接池的中间层基础设施使用,例如数据库连接池。

ConnectionProxy:连接代理,一般由数据库连接池提供,完成对物理连接的包装,通过代理连接将一些操作交给物理连接去完成,一些操作自己完成,例如:close方法,一般物理连接的close方法是指物理上彻底关闭连接,而Proxy的一般实现是将该ConnectionProxy标记为闲置状态,并将其放回到连接池中,一般下次可用。

Pool:连接池的核心实现者,主要完成ConnectionProxy的存储,以及连接的获取、释放、创建、物理销毁、连接可用性探测、性能监控。连接池的核心,直接影响到连接池的高可用性、高并发、高性能等特性。

DataSource:是指JDBC规范中的DataSource,与接口java.sql.DataSource相对应。

PooledDataSource:连接池对DataSource的一种实现,意在从Pool中获取连接,达到连接的可重用性。

         掌握了几个概念之后,就可以很清楚的知晓连接池的一般实现了,一般是应用获取一个数据库连接,需要通过调用PoolingDataSource的getConnection方法,getConnection方法就是从Pool中获取一个可用的连接,如果池中有现成的可用的,则直接返回,并将连接标记为繁忙状态。如果当前连接池中无可用连接,则会从驱动程序中获取一个物理连接,并将其包装为ConnectionProxy,返回到Pool中,将其标记为繁忙再次返回给应用。

         而连接的关闭逻辑是这样的,应用App在试用完连接时,调用close方法进行连接的释放操作,而这时调用的是ConnectionProxy的close,ConnectionProxy方法一般是将该连接重新释放到连接中,并标记为闲置状态,以便其他线程去获取。

 

下面举个具体的例子,例如DBCP框架中的各个角色与其对应类的实现。

C3p0的实现

 

BoneCP的实现

由此可见在大部分的连接池框架中都可以找到这几个概念。

几个参数

         数据库能否正常工作还要依赖具体环境和应用场景的具体配置,对于数据库连接池的调优也往往是集中在这几个参数上。这几个参数的配置在不同的应用甚至是不同的压力下,都应当有不同的配置,所以我们需要不断的测试调整这些参数以此达到数据库连接池最优。没有绝对正确的参数,只有适合某些场景下的参数,设置是相同的应用在不同的访问压力下,也应当有不同的参数配置。

         虽然目前市场上Java的开源框架繁多,但是大部分的连接池配置参数都有大同小异。首先是连接池在启动时会初始化initMinNum个数据库连接,然后在应用压力逐渐上升时,不断的创建连接,直到MaxNum个,当压力回落时,会逐渐的释放连接直到闲置连接数达到MaxIdleNum。还有一个参数需要特别注意,就是MaxWaitTime,该参数的含义为当数据库连接池中没有可供使用的闲置连接时,连接池会在等待MaxWaitTime时间后会抛出异常或者是其他方式通知调用者。所以该参数应当分场景和分情况来测试,开发环境和测试环境应当尽量设置为较短的时间,例如10秒钟,为的是将问题尽量的暴露出来,引起人们的注意,去排查问题。而在生产环境中应当设置为稍小于用户可接收的等待时间。例如一分钟。

1) 最小连接数

  是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费;

2) 最大连接数

  是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。

3) 如果最小连接数与最大连接数相差太大,

  那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。

Java中开源的数据库连接池

在Java中开源的数据库连接池有以下几种 :   

C3P0:C3P0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。

Proxool:这是一个Java SQL Driver驱动程序,提供了对你选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中。完全可配置。快速,成熟,健壮。可以透明地为你现存的JDBC驱动程序增加连接池功能。

Jakarta DBCP:DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序用使用。

DDConnectionBroker: DDConnectionBroker是一个简单,轻量级的数据库连接池。   

DBPool: DBPool是一个高效的易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池使你能够开发一个满足自已需求的数据库连接池。   

XAPool: XAPool是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。

Primrose:Primrose是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5,Resin3与JBoss3.它同样也有一个独立的版本可以在应用程序中使用而不必运行在容器中。Primrose通过一个web接口来控制SQL处理的追踪,配置,动态池管理。在重负荷的情况下可进行连接请求队列处理。

SmartPool: SmartPool是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks),连接阻塞,打开的JDBC对象如Statements,PreparedStatements等. SmartPool的特性包括支持多个pools,自动关闭相关联的JDBC对象, 在所设定time-outs之后察觉连接泄漏,追踪连接使用情况, 强制启用最近最少用到的连接,把SmartPool"包装"成现存的一个pool等。   

MiniConnectionPoolManager: MiniConnectionPoolManager是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。

BoneCP: BoneCP是一个快速,开源的数据库连接池。帮你管理数据连接让你的应用程序能更快速地访问数据库。比C3P0/DBCP连接池快25倍。

总结

         这些数据库连接池实现各自都有自己的特点,例如:BoneCP已分治的原理,将一个Pool分化成为若干个parttition从而解决高 并发,达到高性能。尽管如此,但还是可以看的出,大部分的连接池都遵循以上原则,可以找到以上几个概念的影子,既然是这样就可以针对大部分的连接池开发出一个通用的监控工具。下篇博文我将利用通用原理,开发适用大部分数据库连接池的监控工具,以便大家能够对数据库连接池调优。

0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics