調整 JDBC 連線池大小的最佳實踐
一、簡介
在本教學中,我們將討論調整 JDBC 連線池大小的最佳策略。
2. 什麼是 JDBC 連線池,為什麼要使用它?
JDBC 連線池是一種用於有效管理資料庫連線的機制。建立資料庫連線涉及幾個耗時的步驟,例如:
- 開啟與資料庫的連接
- 驗證使用者身份
- 建立 TCP 套接字進行通信
- 透過套接字發送和接收數據
- 關閉連線和 TCP 套接字
對每個使用者請求重複這些步驟可能效率很低,特別是對於具有許多使用者的應用程式。 JDBC 連線池透過提前建立可重複使用連線池來解決此問題。當應用程式啟動時,它會在池中建立並維護資料庫連接。池連接管理器管理這些連接並處理它們的生命週期。
當客戶端請求連接時,池管理器會從池中提供一個連接,而不是建立一個新連接。一旦客戶端完成,連線將返回池中以供重用,而不是被關閉。這種連接的重複使用可以節省時間和資源,從而顯著提高應用程式效能。
3. 為什麼確定 JDBC 連線池的最佳大小很重要?
確定 JDBC 連線池的最佳大小對於平衡效能和資源利用率至關重要。小池可能會導致更快的連接訪問,但如果沒有足夠的連接來滿足所有請求,則可能會導致延遲。相反,大型池可確保有更多連線可用,從而減少佇列中花費的時間,但可能會減慢對連線表的存取速度。
下表總結了調整連線池大小時要考慮的優缺點:
連線池大小 | 優點 | 缺點 |
---|---|---|
小泳池 | 更快地存取連接表 | 我們可能需要更多連線來滿足請求。請求可能會在佇列中花費更多時間。 |
大型泳池 | 更多連線來滿足請求。請求在隊列中花費更少(或沒有)時間 | 存取連線表速度較慢 |
4. 決定 JDBC 連線池大小時要考慮的要點
在決定池大小時,我們需要考慮幾個因素。首先,我們應該評估平均事務回應時間和資料庫查詢所花費的時間。負載測試可以幫助確定這些時間,建議計算池大小時額外增加 25% 的容量來處理意外負載。其次,連接池應該能夠根據實際需求進行增長和收縮。我們也可以使用日誌語句或 JMX 監視來監視系統,以動態調整池大小。
此外,我們應該考慮每個頁面載入執行多少個查詢以及每個查詢的持續時間。為了獲得最佳性能,我們從幾個連接開始,然後逐漸增加。每個節點有 8 到 16 個連接的池通常是最佳的。我們還可以根據監控統計資料調整Idle Timeout
和Pool Resize Quantity
值。
5. 控制 JDBC 連線池的基本設置
這些基本設定控制池大小:
連線池屬性 | 描述 |
---|---|
初始池大小和最小池大小 | 創建池時的大小及其允許的最小大小 |
最大池大小 | 池大小上限 |
池調整大小數量 | 空閒逾時到期時要刪除的連線數。空閒時間超過超時時間的連接將被刪除,一旦池達到初始和最小池大小,就會停止連接 |
最大空閒連線數 | 池中允許的最大空閒連線數。如果空閒連接數超過此限制,則關閉多餘的連接,釋放資源 |
最小空閒連線數 | 池中保留的最小空閒連線數 |
最長等待時間 | 應用程式等待連接可用的最長時間 |
驗證查詢 | 用於在將連接移交給應用程式之前驗證連接的 SQL 查詢 |
6. 調整 JDBC 連線池大小的最佳實踐
以下是調整 JDBC 連線池以確保與資料庫執行個體的健康連線的一些最佳實務。
6.1.驗證連接 SQL
首先,我們新增驗證 SQL 查詢以啟用連線驗證。它確保池中的連接定期測試並保持健康。它還可以快速檢測並記錄資料庫故障,使管理員能夠立即採取行動。選擇最佳驗證方法(例如元資料或表格查詢)。經過充分的監控後,關閉連線驗證可以進一步提高效能。以下是使用最受歡迎的 JDBC 連線池(即Hikari
)來配置它的範例:
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:your_database_url");
config.setUsername("your_database_username");
config.setPassword("your_database_password");
config.setConnectionTestQuery("SELECT 1");
HikariDataSource dataSource = new HikariDataSource(config);
6.2.最大池大小
我們還可以調整最大池大小,使其足以滿足使用該應用程式的使用者數量。有必要處理異常負載。即使在非生產環境中,也可能需要多個同時連接:
config.setMaximumPoolSize(20);
6.3.最小池大小
然後,我們應該調整最小池大小以適應應用程式的負載。如果多個應用程式/伺服器連接到同一個資料庫,則擁有足夠的最小池大小可確保保留的資料庫連線可用:
config.setMinimumIdle(10);
6.4.連線逾時
我們可以考慮的另一個方面是配置阻塞逾時(以毫秒為單位),以便連接請求等待連接變得可用,而不必無限期等待。建議使用 3 到 5 秒的合理值:
config.setConnectionTimeout(5000);
6.5.空閒超時
將空閒超時設定為適合應用程式的值。對於共用資料庫,較低的空閒逾時(例如,30 秒)可以使空閒連線可供其他應用程式使用。較高的值(例如 120 秒)可防止為專用資料庫頻繁建立連線:
config.setIdleTimeout(30000);
// or
config.setIdleTimeout(120000);
6.6。線程池調優
使用負載/壓力測試來估計最小和最大池大小。估計池大小的常用公式是connections = (2 * core_count) + number_of_disks
。此公式提供了一個起點,但要求可能會根據 I/O 阻塞和其他因素而有所不同。從較小的池大小開始,然後根據測試逐漸增加池大小。像pg_stat_activity
這樣的監控工具可以幫助確定連線是否空閒太多,表示需要縮小池大小:
int coreCount = Runtime.getRuntime().availableProcessors();
int numberOfDisks = 2; // assuming two no. of disc
int connections = (2 * coreCount) + numberOfDisks;
config.setMaximumPoolSize(connections);
config.setMinimumIdle(connections / 2);
6.7.事務隔離等級
選擇滿足並發性和一致性需求的效能最佳的隔離等級。除非必要,否則避免指定隔離等級。如果指定,請將不以程式設計方式變更隔離等級的應用程式的Isolation Level Guaranteed
設為false
:
try (Connection conn = dataSource.getConnection()) {
conn.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
} catch (SQLException e) {
e.printStackTrace();
}
七、結論
在本文中,我們討論如何設定 JDBC 連線池。透過了解影響連接池大小的因素並遵循調整和監控的最佳實踐,我們可以確保健康的資料庫連接並提高應用程式效能。
與往常一樣,程式碼可以在 GitHub 上取得。