Druid连接池的connectionErrorRetryAttempts、
timeBetweenConnectErrorMillis、breakAfterAcquireFailure参数使用:

当获取连接时:

public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException {
    init();

    if (filters.size() > 0) {
        FilterChainImpl filterChain = new FilterChainImpl(this);
        return filterChain.dataSource_connect(this, maxWaitMillis);
    } else {
        return getConnectionDirect(maxWaitMillis);
    }
}

其中的init():

  private final CountDownLatch initedLatch = new CountDownLatch(2);
  public void init() throws SQLException {
      // inited初始值为false
        if (inited) {
            return;
        }
        // 此处跳过部分代码
    ......
        try{
            ......
            // 开启创建连接的线程
            createAndStartCreatorThread();
            // 开启销毁连接的线程
            createAndStartDestroyThread();

            // 初始化时为:new CountDownLatch(2);上述两个方法中会执行initedLatch.countDown
            initedLatch.await();
            ......
        }finally{
            // 对 inited 进行更新,后续不再改为false,除非调用restart()方法
            inited = true;
            lock.unlock();

            // 如果初始化成功,则打印初始化的日志:
            LOG.info(msg);
        }

    }
// 进行初始化时,开启线程 createConnectionThread.start();
    protected void createAndStartCreatorThread() {
        if (createScheduler == null) {
            String threadName = "Druid-ConnectionPool-Create-" + System.identityHashCode(this);
            createConnectionThread = new CreateConnectionThread(threadName);
            createConnectionThread.start();
            return;
        }

        initedLatch.countDown();
    }
    public class CreateConnectionThread extends Thread {

        public CreateConnectionThread(String name){
            super(name);
            this.setDaemon(true);
        }

        public void run() {
            initedLatch.countDown();

            long lastDiscardCount = 0;
            int errorCount = 0;
            // 死循环创建connection
            for (;;) {
                // addLast
                ......
                try {
                   		 ......
                        // 必须存在线程等待,才创建连接
                        ......
                        // 防止创建超过maxActive数量的连接
                        ......
                PhysicalConnectionInfo connection = null;

                try {
                    // 创建connection的方法
                    connection = createPhysicalConnection();
                    setFailContinuous(false);
                } catch (SQLException e) {
                    LOG.error("create connection error, url: " + jdbcUrl + ", errorCode " + e.getErrorCode()
                              + ", state " + e.getSQLState(), e);

                    errorCount++;
                 // 如果创建连接失败次数超过了配置项:connectionErrorRetryAttempts并且等待时间>0
                    if (errorCount > connectionErrorRetryAttempts && timeBetweenConnectErrorMillis > 0) {
                        // fail over retry attempts
						......
                        // 查看配置项 breakAfterAcquireFailure
                        if (breakAfterAcquireFailure) {
                            break;
                        }

                        try {
                            // 根据配置进行睡眠
                            Thread.sleep(timeBetweenConnectErrorMillis);
                        } catch (InterruptedException interruptEx) {
                            break;
                        }
                    }
                } catch (RuntimeException e) {
                    LOG.error("create connection error", e);
                    setFailContinuous(true);
                    continue;
                } catch (Error e) {
                    LOG.error("create connection error", e);
                    setFailContinuous(true);
                    break;
                }

                if (connection == null) {
                    continue;
                }

                boolean result = put(connection);
                if (!result) {
                    JdbcUtils.close(connection.getPhysicalConnection());
                    LOG.info("put physical connection to pool failed.");
                }

                errorCount = 0; // reset errorCount
            }
        }
    }

CreateConnectionThread运行的线程,是一个死循环,一直进行创建连接,其中退出循环的相关配置项:

connectionErrorRetryAttempts: 创建连接失败重试次数
timeBetweenConnectErrorMillis:失败次数到达connectionErrorRetryAttempts值后,睡眠timeBetweenConnectErrorMillis时间,然后继续进行创建连接
breakAfterAcquireFailure:在进行睡眠之前,先查看该配置项是否为true,如果是,则退出死循环,此处会导致后续再也不进行创建连接(因为此处线程开启,仅在 createAndStartCreatorThread()方法中, 而该方法在 init() 方法中,在进行初始化时,有一个 inited 标志值,第一次进行初始化后,就将该值置为 true, 后续不再改为false,除非调用 restart()方法)
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐