强大的数据库连接池 阿里druid 学习

https://www.cnblogs.com/niejunlei/p/5977895.html

Druid源码分析博客 :
博客1 : https://www.cnblogs.com/ZhangZiSheng001/p/12175893.html
源码详解系列(六) ------ 全面讲解druid的使用和源码

博客2: https://www.cnblogs.com/hama1993/p/11421576.html
池化技术(一)Druid是如何管理数据库连接的?

博客3 :https://www.cnblogs.com/sgw1018/p/druid.html
为什么要使用连接池

博客4:https://zhuanlan.zhihu.com/p/513955742
druid连接池中的连接数与预期不一致的一次分析

 

简单认识

 

 

 

源码分析

Druid源码分析:
CreateConnectionThread 和 CreateConnectionTask   
DestroyConnectionThread 和 DestroyTask

DruidConnectionHolder
DruidPooledConnection

DruidDataSource

异步使用:
ScheduledExecutorService createScheduler
ScheduledExecutorService destroyScheduler

创建物理连接唯一入口:
com.alibaba.druid.pool.DruidAbstractDataSource#createPhysicalConnection()
com.alibaba.druid.pool.DruidDataSource#put(com.alibaba.druid.pool.DruidAbstractDataSource.PhysicalConnectionInfo)

获取连接 
com.alibaba.druid.pool.DruidDataSource#getConnectionDirect

 

参数认识

官方文档:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8

1.连接池大小
initialSize:初始连接大小
maxActive:  最大连接池数量
minldle:    最小连接池数量
maxWait:     获取连接的最长等待时间 毫秒
2.连接检测
timeBetweenEvictionRunsMillis:用于控制回收线程的轮询时间间隔(默认1分钟)
minEvictableldleTimeMillis:(最小空闲时间,默认30分钟)       
maxEvictableIdleTimeMillis:(最大空闲时间,默认7小时)

 

public class DruidProperties {

    private static final Log log = Log.get();

    /**
     * oracle校验语句
     */
    private final String ORACLE_VALIDATE_QUERY_SQL = "select 1 from dual";

    /**
     * postgresql校验语句
     */
    private final String POSTGRESQL_VALIDATE_QUERY_SQL = "select version()";

    /**
     * sqlserver校验语句
     */
    private final String SQLSERVER_VALIDATE_QUERY_SQL = "select 1";

    /**
     * mysql校验语句
     */
    private final String MYSQL_VALIDATE_QUERY_SQL = "select 1";

    private String url;

    private String username;

    private String password;

    private String driverClassName;

    private Integer maxActive = 20;  //连接池最大连接数
    private Integer initialSize = 1; //连接池初始物理连接数
    private Integer minIdle = 0;     //最小空闲连接数
    private Integer maxWait = 2 * 1000;  // 获取连接的最大等待时长 (单位:毫秒)

    private Integer timeBetweenEvictionRunsMillis = 1 * 60 * 1000; //1 min destroy线程需要间隔多久检测一次

    private Integer minEvictableIdleTimeMillis = 2 * 60 * 1000; //2 min

    private String validationQuery;

    private Boolean testWhileIdle = true;

    private Boolean testOnBorrow = true;

    private Boolean testOnReturn = true;

    private Boolean poolPreparedStatements = true;

    private Integer maxPoolPreparedStatementPerConnectionSize = 20;

    private String filters = "stat,wall";

    private String dataSourceName;

    public void config(DruidDataSource dataSource) {

        //基础属性
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);

        //连接池大小
        dataSource.setInitialSize(initialSize);//定义初始连接数
        dataSource.setMaxActive(maxActive);//最大连接数
        dataSource.setMinIdle(minIdle);//最小空闲连接数
        dataSource.setMaxWait(maxWait);//获取连接的最长等待时间

        //连接检测
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);//配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); //配置一个连接在池中最小生存的时间,单位是毫秒
        dataSource.setValidationQuery(getValidateQueryByUrl(url)); //validationQuery检测:用来检测连接是否有效
        dataSource.setTestWhileIdle(testWhileIdle);//申请连接时,如果空闲时间>timeBetweenEvictionRunsMillis,执行validationQuery检测
        dataSource.setTestOnBorrow(testOnBorrow); //申请连接时 执行validationQuery检测
        dataSource.setTestOnReturn(testOnReturn); //归还连接时 执行validationQuery检测

        //连接泄露回收
        dataSource.setRemoveAbandoned(true); //当空闲时间超过removeAbandonedTimeout时,是否视该连接为泄露连接并删除
        dataSource.setRemoveAbandonedTimeoutMillis(300 * 1000); //泄露的连接可以被删除的超时值, 单位毫秒
        dataSource.setLogAbandoned(true); //标记当Statement或连接被泄露时是否打印程序的stack traces日志

        //缓存语句
        dataSource.setPoolPreparedStatements(poolPreparedStatements);//打开PSCache 是否缓存preparedStatement
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); //指定每个连接上PSCache的大小

        //过滤器
        try {
            dataSource.setFilters(filters);
        } catch (SQLException e) {
            log.error(">>> 数据库连接池初始化异常:{}", e.getMessage());
        }
    }

    private String getValidateQueryByUrl(String url) {
        if (url.contains("oracle")) {
            return ORACLE_VALIDATE_QUERY_SQL;
        } else if (url.contains("pgsql")) {
            return POSTGRESQL_VALIDATE_QUERY_SQL;
        } else if (url.contains("mysql")) {
            return SQLSERVER_VALIDATE_QUERY_SQL;
        } else {
            return MYSQL_VALIDATE_QUERY_SQL;
        }
    }

}

 

源码分析

 

jvm监测工具

 

posted @ 2019-04-04 22:27  Peter.Jones  阅读(162)  评论(0编辑  收藏  举报