分享

java数据库连接池Druid

 昵称21365845 2015-06-04

        Druid是阿里巴巴的一个开源项目,据该网站称:Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。

        上述内容难免有水分,但是如果真如他所说Druid已经在阿里巴巴和淘宝等大型网站及系统上被充分使用及测试的话,那么Druid还是值得信赖的,毕竟任何有信誉公司不会拿这个去开玩笑。

 

        Druid官网:http://code./wiki/display/Druid/Home

 

        Druid有以下几点优势或好处:

  • 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
  • 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
  • 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
  • SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
  • 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。

        看到上面的这些Druid的好处你是否已经心动了?下面就让我们一起来实验一下。

 

        1.下载Druid(http://code./mvn/releases/com/alibaba/druid/),目前Druid最新版本为0.2.23,可以选择源码,javadoc,jar等。

        2.还是在之前举例的项目基础上添加Druid代码,代码其实很简单,把之前的c3p0改改就能用:

Java代码  收藏代码
  1. /** 
  2.  * Druid 
  3.  */  
  4. public void getUsrInfoWithDruid(Integer usrId) {  
  5.     String sql="SELECT * FROM USER u WHERE u.USR_ID=" + usrId;  
  6.   
  7.     try {  
  8.         //通过Map方式设置Druid参数  
  9.         Map<String, String> druidMap=new HashMap<String, String>();  
  10.         druidMap.put(DruidDataSourceFactory.PROP_USERNAME, user);  
  11.         druidMap.put(DruidDataSourceFactory.PROP_PASSWORD, passwd);  
  12.         druidMap.put(DruidDataSourceFactory.PROP_URL, jdbcUrl);  
  13.         druidMap.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, driver);  
  14.         //通过DruidDataSourceFactory获取DataSource实例  
  15.         dataSource=DruidDataSourceFactory.createDataSource(druidMap);  
  16.         conn=dataSource.getConnection();  
  17.         Statement st=conn.createStatement();  
  18.         ResultSet result=st.executeQuery(sql);  
  19.         while(result.next()) {  
  20.             System.out.println("Druid:begin");  
  21.             System.out.println("Name:" + result.getString("NAME"));  
  22.             System.out.println("Druid:end");  
  23.         }  
  24.         result.close();  
  25.         st.close();  
  26.         conn.close();  
  27.     } catch(Exception e) {  
  28.         e.printStackTrace();  
  29.     }  
  30. }  

 

        以上是利用Map方式向Druid传递参数,这种方式基本上用不到。

 

        3.利用属性文件传递参数:

 

Xml代码  收藏代码
  1. #MySQL驱动  
  2. druid.driverClassName=com.mysql.jdbc.Driver  
  3. #MySQL连接地址  
  4. druid.url=jdbc\:mysql\://192.168.0.8\:3306/test  
  5. #数据库用户  
  6. druid.username=moster  
  7. #该用户密码  
  8. druid.password=shzygjrmdwg  
  9. #自动提交  
  10. druid.defaultAutoCommit=false  
  11. #只读设置  
  12. druid.defaultReadOnly=false  
  13. druiddruid.defaultTransactionIsolation=  
  14. druid.defaultCatalog=  
  15. #连接池最大使用连接数量  
  16. druid.maxActive=25  
  17. #连接池最大空闲  
  18. druid.maxIdle=25  
  19. #连接池最小空闲  
  20. druid.minIdle=1  
  21. #初始化连接池大小  
  22. druid.initialSize=1  
  23. #连接等待时间,默认:-1  
  24. druid.maxWait=3000  
  25. druiddruid.testOnBorrow=  
  26. druid.testOnReturn=  
  27. #检测间隔,检测需要关闭的空闲连接,单位:毫秒  
  28. druiddruid.timeBetweenEvictionRunsMillis=  
  29. druid.numTestsPerEvictionRun=  
  30. #一个连接在池中最小生存的时间,单位:毫秒  
  31. druiddruid.minEvictableIdleTimeMillis=  
  32. druid.testWhileIdle=  
  33. #测试SQL  
  34. druid.validationQuery=  
  35. #测试超时时间  
  36. druid.validationQueryTimeout=  
  37. #初始化连接SQL  
  38. druiddruid.initConnectionSqls=  
  39. druid.accessToUnderlyingConnectionAllowed=  
  40. #移除被废弃连接  
  41. druid.removeAbandoned=  
  42. #超时时间  
  43. druid.removeAbandonedTimeout=  
  44. #日志记录  
  45. druid.logAbandoned=  
  46. #PreparedStatements  
  47. druid.poolPreparedStatements=  
  48. #PreparedStatement最大数量  
  49. druid.maxOpenPreparedStatements=  
  50. #属性配置文件  
  51. druid.connectionProperties=  
  52. #filters配置  
  53. druid.filters=  
  54. #Exception处理  
  55. druid.exceptionSorter=  
  56. #Exception处理类名  
  57. druid.exception-sorter-class-name=  
  58. #初始化  
  59. druid.init=  

 

        官网居然连这些属性的解释都没有,以上是我自己翻译的,如有偏差请及时指正。

 

        4.将原创建DataSource方法修改为:

Java代码  收藏代码
  1. Properties p=new Properties();  
  2. p.load(getClass().getResourceAsStream("/druid.properties"));  
  3. //通过属性文件设置Druid参数  
  4. dataSource=DruidDataSourceFactory.createDataSource(p);  

        Druid的参数可以参考DruidDataSourceFactory类的源码,其中参数的命名规则与c3p0,DBCP非常像,也比较容易理解,以下是具体参数:

Java代码  收藏代码
  1. String    PROP_DEFAULTAUTOCOMMIT                   = "defaultAutoCommit";  
  2. String    PROP_DEFAULTREADONLY                     = "defaultReadOnly";  
  3. String    PROP_DEFAULTTRANSACTIONISOLATION         = "defaultTransactionIsolation";  
  4. String    PROP_DEFAULTCATALOG                      = "defaultCatalog";  
  5. String    PROP_DRIVERCLASSNAME                     = "driverClassName";  
  6. String    PROP_MAXACTIVE                           = "maxActive";  
  7. String    PROP_MAXIDLE                             = "maxIdle";  
  8. String    PROP_MINIDLE                             = "minIdle";  
  9. String    PROP_INITIALSIZE                         = "initialSize";  
  10. String    PROP_MAXWAIT                             = "maxWait";  
  11. String    PROP_TESTONBORROW                        = "testOnBorrow";  
  12. String    PROP_TESTONRETURN                        = "testOnReturn";  
  13. String    PROP_TIMEBETWEENEVICTIONRUNSMILLIS       = "timeBetweenEvictionRunsMillis";  
  14. String    PROP_NUMTESTSPEREVICTIONRUN              = "numTestsPerEvictionRun";  
  15. String    PROP_MINEVICTABLEIDLETIMEMILLIS          = "minEvictableIdleTimeMillis";  
  16. String    PROP_TESTWHILEIDLE                       = "testWhileIdle";  
  17. String    PROP_PASSWORD                            = "password";  
  18. String    PROP_URL                                 = "url";  
  19. String    PROP_USERNAME                            = "username";  
  20. String    PROP_VALIDATIONQUERY                     = "validationQuery";  
  21. String    PROP_VALIDATIONQUERY_TIMEOUT             = "validationQueryTimeout";  
  22. String    PROP_INITCONNECTIONSQLS                  = "initConnectionSqls";  
  23. String    PROP_ACCESSTOUNDERLYINGCONNECTIONALLOWED = "accessToUnderlyingConnectionAllowed";  
  24. String    PROP_REMOVEABANDONED                     = "removeAbandoned";  
  25. String    PROP_REMOVEABANDONEDTIMEOUT              = "removeAbandonedTimeout";  
  26. String    PROP_LOGABANDONED                        = "logAbandoned";  
  27. String    PROP_POOLPREPAREDSTATEMENTS              = "poolPreparedStatements";  
  28. String    PROP_MAXOPENPREPAREDSTATEMENTS           = "maxOpenPreparedStatements";  
  29. String    PROP_CONNECTIONPROPERTIES                = "connectionProperties";  
  30. String    PROP_FILTERS                             = "filters";  
  31. String    PROP_EXCEPTION_SORTER                    = "exceptionSorter";  
  32. String    PROP_EXCEPTION_SORTER_CLASS_NAME         = "exception-sorter-class-name";  
  33. String    PROP_INIT                                = "init";  

 

        Druid监控:

        同Proxool一样Druid也提供了监控功能,而且更强大!

        Druid的监控配置起来跟Proxool类似,其实我的感觉就是Druid把现在主流的连接池优点结合起来了,很有中国人做东西的“风格”。

Xml代码  收藏代码
  1. <!-- Druid监控Servlet -->  
  2. <servlet>  
  3.     <servlet-name>DruidStatView</servlet-name>  
  4.     <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>  
  5. </servlet>  
  6. <servlet-mapping>  
  7.     <servlet-name>DruidStatView</servlet-name>  
  8.     <url-pattern>/druid/*</url-pattern>  
  9. </servlet-mapping>  

 

        打开浏览器就可以看到监控页面了。

       下图是Druid官网给出的几种连接池的对比表格,从数据上来看Druid在各方面都占有很大的优势,实际情况还需要实践去检验。



 
 

        LRU
        LRU是一个性能关键指标,特别Oracle,每个Connection对应数据库端的一个进程,如果数据库连接池遵从LRU,有助于数据库服务器优化,这是重要的指标。在测试中,Druid、DBCP、Proxool、JBoss是遵守LRU的。BoneCP、C3P0则不是。BoneCP在mock环境下性能可能好,但在真实环境中则就不好了。

 

        PSCache
        PSCache是数据库连接池的关键指标。在Oracle中,类似SELECT NAME FROM USER WHERE ID = ?这样的SQL,启用PSCache和不启用PSCache的性能可能是相差一个数量级的。Proxool是不支持PSCache的数据库连接池,如果你使用Oracle、SQL Server、DB2、Sybase这样支持游标的数据库,那你就完全不用考虑Proxool。

 

        PSCache-Oracle-Optimized
        Oracle 10系列的Driver,如果开启PSCache,会占用大量的内存,必须做特别的处理,启用内部的EnterImplicitCache等方法优化才能够减少内存的占用。这个功能只有DruidDataSource有。如果你使用的是Oracle Jdbc,你应该毫不犹豫采用DruidDataSource。

 

        ExceptionSorter
        ExceptionSorter是一个很重要的容错特性,如果一个连接产生了一个不可恢复的错误,必须立刻从连接池中去掉,否则会连续产生大量错误。这个特性,目前只有JBossDataSource和Druid实现。Druid的实现参考自JBossDataSource。

 

        监控
        DruidDataSource自身提供有NotEmptyWaitCount、PSCahcheHitCount等有用的监控属性,通过配置StatFilter能够监控SQL的执行情况。

 

        扩展
        DruidDataSource提供基于Filter-Chain模式的模式的扩展。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多