Druid连接池源码解析(1)DruidDataSource

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Druid连接池源码解析(1)DruidDataSource相关的知识,希望对你有一定的参考价值。

参考技术A DruidDataSource为整个链接池的基础入口,实现了JDBC的Datasource

参数用来控制锁的公平性,默认false非公平
configFromPropety 方法从配置中,初始化各种配置属性,属性及其多,浏览一下即可

看一下super的构造函数,定义了锁的状态

然后调用init()方法初始化
init又非常得长,主要做了如下几件事情:

主要链路
getConnectionDirect(maxWaitMillis)->
getConnectionInternal(maxWaitMillis)->
createPhysicalConnection()->
DruidConnectionHolder ->pollLast()
失败重新创建一个->new DruidConnectionHolder(this, pyConnInfo);
最后返回通过Holder获取的connection new DruidPooledConnection(holder);

生成DataSourceId的时候,用了几个原子类来记录偏移量,后续看到再标注

看源码的方法,可以从Test单元测试类开始
DruidDataSourceTest 初始化到关闭的流程走了一遍

Druid连接池

一、Druid简介

  Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

二、Druid下载

  正式版本下载:
     maven中央仓库:  http://central.maven.org/maven2/com/alibaba/druid/ 

三、Druid源码

  Driud是一个开源项目,源码托管在github上,源代码仓库地址是https://github.com/alibaba/druid 。同时每次Druid发布正式版本和快照的时候,都会把源码打包,你可以从上面的下载地址中找到相关版本的源码。

四、Druid配置

  Druid 0.1.18之后版本都发布到maven中央仓库中,所以你只需要在项目的pom.xml中加上dependency就可以了。例如:

<!-- druid数据库连接池依赖包alibb的( druid能够提供强大的监控和扩展功能)-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>${druid.version}</version>
</dependency>

  也可以选择 Maven仓库查找公共的仓库地址:

http://www.mvnrepository.com/artifact/com.alibaba/druid

五、Druid监控

  Druid的监控统计功能是通过filter-chain扩展实现,如果你要打开监控统计功能,配置StatFilter。

  Druid内置提供一个StatFilter,用于统计监控信息。

  StatFilter配置:

  5.1、别名配置

  StatFilter的别名是stat,这个别名映射配置信息保存在:druid-xxx.jar!/META-INF/druid-filter.properties。

  在spring中使用别名配置方式如下:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ... ...
    <property name="filters" value="stat" />
</bean>

  5.2、组合配置

  StatFilter可以和其他的Filter配置使用,比如: 

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ... ...
    <property name="filters" value="stat,log4j" />
</bean>

  在上面的配置中,StatFilter和Log4jFilter组合使用。

  5.3、通过proxyFilters属性配置

  别名配置是通过filters属性配置的,filters属性的类型是String。如果需要通过bean的方式配置,使用proxyFilters属性。

<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">    
    <property name="slowSqlMillis" value="10000" />
    <property name="logSlowSql" value="true" />
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ... ...
    <property name="filters" value="log4j" />
    <property name="proxyFilters">
      <list>
        <ref bean="stat-filter" />
      </list>
    </property>
</bean>

  其中filters和proxyFilters属性是组合关系的,不是替换的,在上面的配置中,dataSource有了两个Filter,StatFilter和Log4jFilter。

  5.4、SQL合并配置

  当你程序中存在没有参数化的sql执行时,sql统计的效果会不好。比如:

select * from t where id = 1 
select * from t where id = 2
select * from t where id = 3

  在统计中,显示为3条sql,这不是我们希望要的效果。StatFilter提供合并的功能,能够将这3个SQL合并为如下的SQL。

select * from t where id = ?

  配置StatFilter的mergeSql属性:

<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">    
    <property name="mergeSql" value="true" />
</bean>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ... ...
    <property name="proxyFilters">
      <list>
        <ref bean="stat-filter" />
      </list>
    </property>
</bean>

  StatFilter支持一种简化配置方式,和上面的配置等同的。如下:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">    
    ... ...
    <property name="filters" value="mergeStat" />
</bean>

  mergeStat是的MergeStatFilter缩写,我们看MergeStatFilter的实现:

 public class MergeStatFilter extends StatFilter {    
    public MergeStatFilter() {
      super.setMergeSql(true);
    }
}

  也可以通过connectProperties属性来打开mergeSql功能,例如:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">    
    ... ...
    <property name="filters" value="stat" />
    <property name="connectionProperties" value="druid.stat.mergeSql=true" />
</bean>

  或者通过增加JVM的参数配置:

-Ddruid.stat.mergeSql=true

  合并SQL对tddl的支持:在druid-0.2.17版本之后,sql合并支持tddl,能够对分表进行合并。

  5.5、慢SQL记录

  StatFilter属性slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢。slowSqlMillis的缺省值为3000,也就是3秒。

<bean id="stat-filter" class="com.alibaba.druid.filter.stat.StatFilter">    
    <property name="slowSqlMillis" value="10000" />
    <property name="logSlowSql" value="true" />
</bean>

  在上面的配置中,slowSqlMillis被修改为10秒,并且通过日志输出执行慢的SQL。

  slowSqlMillis属性也可以通过connectProperties来配置,例如:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">    
    ... ...
    <property name="filters" value="stat" />
    <property name="connectionProperties" value="druid.stat.slowSqlMillis=5000" />
</bean>

  5.6、合并多个DruidDataSource的监控数据

  缺省多个DruidDataSource的监控数据是各自独立的,在Druid-0.2.17版本之后,支持配置公用监控数据,配置参数为useGloalDataSourceStat。例如:

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">    
    ... ...
    <property name="useGlobalDataSourceStat" value="true" />
</bean>

  或者通过jvm启动参数来指定,例如:

-Ddruid.useGlobalDataSourceStat=true

  全部使用jvm启动参数来配置,可以这样:

-Ddruid.filters=mergeStat -Ddruid.useGlobalDataSourceStat=true

 

  文章转自:http://blog.csdn.net/yinxiangbing/article/details/47905381

 

以上是关于Druid连接池源码解析(1)DruidDataSource的主要内容,如果未能解决你的问题,请参考以下文章

Druid连接池源码解析(2)DruidDataSource-2

Druid数据库连接池源码分析

Druid核心源码解析--DruidDataSource

Druid核心源码解析--DruidDataSource

Druid核心源码解析--DruidDataSource

真难!通过源码告诉你阿里的数据库连接池Druid为啥如此牛逼!