druid 入门相关

druid



入门参考:

官方文档:
https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE
参考其中配置。


                                   ConnectionPool
                              |---------------------------| 
                              |                           |
       getConnection          |                           |    
      (notEmpty.await)        |                           |   
      (lowWater.signal)       |                           |
      (maxActive.await)       |                           |
  <-------------------------- |                           |
  <-------------------------- |                           |
  <-------------------------- |                           |
                              |                           |
                              |                           |
  --------------------------> |                           |
  --------------------------> |                           |    销毁多余连接的线程
  --------------------------> |                           |    (highWater.awati, idleTimeout.await)
    close                     |                           | --------------------------------------> 
    (highWater.signal)        |                           |
    (maxActive.signal)        |                           |  
                              |                           |
                              |                           |
              产生连接的线程     |                           |
     (lowWater.await)         |                           |
     (notEmpty.signal)        |                           |
  --------------------------> |                           |
                              |                           |
                              |---------------------------|
                              
五个Condition:notEmpty、maxActive、lowWater、hightWater, idleTime

    public Connection createPhysicalConnection(String url, Properties info) throws SQLException {
        Connection conn;
        if (getProxyFilters().size() == 0) {
            conn = getDriver().connect(url, info);
        } else {
            conn = new FilterChainImpl(this).connection_connect(info);
        }

        createCountUpdater.incrementAndGet(this);

        return conn;
    }

对比proxool连接池:

proxool太古老,不方便监控,参数控制等也有些问题:比如
maximumConnectionLifetime 是通过创建时间来控制的:

/**
 * The age in millseconds since this connection was built
 */
long getAge();


以下是过期清理的代码:
HouseKeeper.sweep()
        // Now to check whether the connection is due for expiry
       if (proxyConnection.getAge() > definition.getMaximumConnectionLifetime()) {
           final String reason = "age is " + proxyConnection.getAge() + "ms";
           // Check whether we can make it offline
           if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_AVAILABLE, ProxyConnectionIF.STATUS_OFFLINE)) {
               if (proxyConnection.setStatus(ProxyConnectionIF.STATUS_OFFLINE, ProxyConnectionIF.STATUS_NULL)) {
                   // It is.  Expire it now .
                   connectionPool.expireProxyConnection(proxyConnection, ConnectionListenerIF.MAXIMUM_CONNECTION_LIFETIME_EXCEEDED, reason, ConnectionPool.REQUEST_EXPIRY);
               }
           } else {
               // Oh no, it's in use.  Never mind, we'll mark it for expiry
               // next time it is available.  This will happen in the
               // putConnection() method.
               proxyConnection.markForExpiry(reason);
               if (log.isDebugEnabled()) {
                   log.debug(connectionPool.displayStatistics() + " - #" + FormatHelper.formatMediumNumber(proxyConnection.getId())
                           + " marked for expiry.");
               }
           } // END if (poolableConnection.setOffline())
       } // END if (poolableConnection.getAge() > maximumConnectionLifetime)   


生产连接池,小于minimumConnectionCount则添加,小于最小空闲数prototypeCount也添加。
Prototyper.sweep()
while (!cancel && connectionPool.isConnectionPoolUp()) {

            String reason = null;
            if (connectionCount >= getDefinition().getMaximumConnectionCount()) {
                // We don't want to make any more that the maximum
                break;
            } else if (connectionCount < getDefinition().getMinimumConnectionCount()) {
                reason = "to achieve minimum of " + getDefinition().getMinimumConnectionCount();
            } else if (connectionPool.getAvailableConnectionCount() < getDefinition().getPrototypeCount()) {
                reason = "to keep " + getDefinition().getPrototypeCount() + " available";
            } else {
                // Nothing to do
                break;
            }

            ProxyConnectionIF freshlyBuiltProxyConnection = null;
            try {
                // If it has been shutdown then we should just stop now.
                if (!connectionPool.isConnectionPoolUp()) {
                    break;
                }
                freshlyBuiltProxyConnection = buildConnection(ConnectionInfoIF.STATUS_AVAILABLE, reason);
                somethingDone = true;
            } catch (Throwable e) {
                log.error("Prototype", e);
            }
}

以上就会造成非高峰期时间段内,如果最小值配的比较大,会固定回收时间重新创建一次连接池的最小个数。
而druid没有这个问题:

DruidDataSource.shrink()
for (int i = 0; i < poolingCount; ++i) {
            DruidConnectionHolder connection = connections[i];

            if (checkTime) {
                if (phyTimeoutMillis > 0) {
                    long phyConnectTimeMillis = currentTimeMillis - connection.connectTimeMillis;
                    if (phyConnectTimeMillis > phyTimeoutMillis) {
                        evictConnections[evictCount++] = connection;
                        continue;
                    }
                }

                long idleMillis = currentTimeMillis - connection.lastActiveTimeMillis;

                if (idleMillis < minEvictableIdleTimeMillis) {
                    break;
                }

                if (checkTime && i < checkCount) {
                    evictConnections[evictCount++] = connection;
                } else if (idleMillis > maxEvictableIdleTimeMillis) {
                    evictConnections[evictCount++] = connection;
                } else if (keepAlive) {
                    keepAliveConnections[keepAliveCount++] = connection;
                }
            } else {
                if (i < checkCount) {
                    evictConnections[evictCount++] = connection;
                } else {
                    break;
                }
            }
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值