Hikari建立鏈接的時機

  • 在鏈接關閉 closeConnection() 的時候,會調用 fillPool() 進行填充到 minimumIdle 個鏈接
  • HikariPool鏈接池初始化 在鏈接池初始化時,會開啓HouseKeeper 去定時檢查,也會調用 fillPool() 去填充,可是若是 minimumIdle爲0 就沒辦法了
  • Hikari申請db鏈接的過程 申請db鏈接的時候,若是超時未獲取到就直接拋異常了;好像並不會去觸發鏈接的建立

在 HikariPool 初始化的時候,已經知道負責鏈接建立的 addConnectionExecutor 這個線程池,那麼只要找到向它提交任務的地方就能夠了;ide

發現 HikariPool 實現了 IBagStateListener#addBagItem 接口,在裏邊執行了鏈接建立的動做spa

// 等待獲取db鏈接的線程數
public void addBagItem(final int waiting)
{
   final boolean shouldAdd = waiting - addConnectionQueueReadOnlyView.size() >= 0; // Yes, >= is intentional.
   if (shouldAdd) {
      addConnectionExecutor.submit(poolEntryCreator);
   }
   else {
      logger.debug("{} - Add connection elided, waiting {}, queue {}", poolName, waiting, addConnectionQueueReadOnlyView.size());
   }
}

再看哪裏會調用 HikariPool#addBagItem, 找到 ConcurrentBag#borrow(timeout, timtUnit) 在從底層鏈接的容器申請db鏈接時,若是沒有可用的 poolEntry,則會 調用 HikariPool#addBagItem 去提交新建db鏈接的任務;線程

因此在鏈接申請 HikariPool#getConnection() → concurrentBag#borrow 失敗的話,也會觸發鏈接的建立debug

HikariPool#addBagItem 和 HouseKeeper 的邏輯不同,addBagItem的場景是此刻db鏈接就不夠用了,須要去建立接口

相關文章
相關標籤/搜索