FlexyPool 指南
一、概述
在本教程中,我們將學習如何將FlexyPool與 Spring Boot 結合使用,以及如何使用 HikariCP 結合使用 H2。它是一個建立在主要連接池之上的強大的連接池管理器。
2. 什麼是FlexyPool?
連接池是現代 Web 應用程序的一個重要方面。因為它確保數據庫連接在多個客戶端之間共享。這就是該技術允許更快、更有效地訪問數據庫的方式。
但是,管理連接池可能是一項複雜且具有挑戰性的任務。當客戶端數量和應用程序的複雜性增加時,它尤其明顯。這正是FlexyPool派上用場的地方。
FlexyPool 是一個強大的連接池管理工具。事實上,它使管理數據庫連接和優化性能變得容易。簡單地說,FlexyPool 充當 Hikari、 [C3P0](http://www.mchange.com/projects/c3p0/)
、 [DBCP2](https://commons.apache.org/proper/commons-dbcp/)
、 [Tomcat](https://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html)
和Vibur
等主要連接池的代理。為了實現其目標,該庫提供了指標和故障轉移策略來幫助按需調整給定池的大小:
2.1. FlexyPool 屬性
FlexyPool 提供了兩個重要的屬性:
-
connectionAcquireTimeThresholdMillis
:指定連接獲取請求的時間閾值。過了這個時間,發布了一個ConnectionAcquireTimeThresholdExceededEvent
。 -
connectionLeaseTimeThresholdMillis
:這是連接返回池之前可以租出的最長時間。當池超過此閾值時,Flexypool 會發布ConnectionLeaseTimeThresholdExceededEvent
。
2.2.靈活池策略
FlexyPool 提供了兩種策略來響應連接池中的連接獲取失敗。
第一個策略是IncrementPoolOnTimeoutConnectionAcquiringStrategy
。使用此策略,如果連接獲取期間出現超時,FlexyPool 會增加目標連接池的最大大小。該策略有兩個選項maxOverflowPoolSize
和timeoutMillis
。
maxOverflowPoolSize
設置目標連接池可以延伸到的最大限制。
timeoutMillis
設置嘗試池增量之前的持續時間。它默認為連接池超時值。
策略RetryConnectionAcquiringStrategy
指示 FlexyPool 在放棄之前重試從池中獲取連接的retryAttempts
次。 retryAttempts
代表嘗試的重試次數。
我們將在FlexyPoolDataSource
配置中設置所有這些策略。
三、安裝
首先,讓我們安裝 HikariCP 連接池:
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
接下來,我們將添加FlexyPool 依賴項、 HikariCP 適配器和Micrometer 適配器:
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-hikaricp</artifactId>
<version>2.2.3</version>
<exclusions>
<exclusion>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-dropwizard-metrics</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.vladmihalcea.flexy-pool</groupId>
<artifactId>flexy-micrometer-metrics</artifactId>
<version>2.2.3</version>
</dependency>
由於我們使用 Micrometer 作為指標實現,因此我們排除了默認使用的 Dropwizard-Metrics。**此外,FlexyPool 還有其他支持的連接池框架的安裝指南**。如果使用的 Java 版本低於 1.8,查閱它也很有用。
4.配置
要啟動並運行 FlexyPool,我們首先需要一個FlexyPoolDataSource
數據源。它需要一個特定於正在使用的連接池的數據源,在我們的例子中是HikariDataSource
數據源。讓我們把它們都設置好。
4.1. HikariDataSource
配置
首先,我們使用內存中的 H2 數據庫配置 Hikari 數據源:
@Bean
public HikariDataSource hikariDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=runscript from 'classpath:/db.sql'");
config.setUsername("");
config.setPassword("");
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
config.addDataSourceProperty("minimumPoolSize", "1");
config.addDataSourceProperty("maximumPoolSize", "3");
config.addDataSourceProperty("connectionTimeout", "1000");
return new HikariDataSource(config);
}
在這裡,我們添加了maximumPoolSize
和connectionTimeout
屬性。正如我們之前看到的,它們對 FlexyPool 的IncrementPoolOnTimeoutConnectionAcquiringStrategy
很有用。
接下來,我們使用HikariDataSource
連接一個配置 bean:
@Bean
public Configuration<HikariDataSource> flexypoolConfiguration() {
HikariDataSource dataSource = hikariDataSource();
return new Configuration.Builder<>(UUID.randomUUID().toString(), dataSource, HikariCPPoolAdapter.FACTORY)
.setMetricsFactory(MicrometerMetrics::new)
.setConnectionProxyFactory(ConnectionDecoratorFactoryResolver.INSTANCE.resolve())
.setMetricLogReporterMillis(TimeUnit.SECONDS.toMillis(5))
.setMetricNamingUniqueName(UniqueNamingStrategy.INSTANCE)
.setJmxEnabled(true)
.setJmxAutoStart(true)
.setConnectionAcquireTimeThresholdMillis(50L)
.setConnectionLeaseTimeThresholdMillis(250L)
.setEventListenerResolver(() -> Arrays.asList(
new ConnectionAcquireTimeoutEventListener(),
new ConnectionAcquireTimeThresholdExceededEventListener(),
new ConnectionLeaseTimeThresholdExceededEventListener()))
.build();
}
此配置:
- 啟用 JMX 報告
- 將指標實現設置為 Micrometer。 Micrometer 適配器默認使用
SimpleMetricsRegistry
。但是,它可以定制為使用集成的監控報告工具,例如Ganglia或Graphite 。 - 向各種連接事件添加偵聽器:
ConnectionAcquireTimeoutEvent
、ConnectionAcquireTimeThresholdExceededEvent
和ConnectionLeaseTimeThresholdExceeded.
值得注意的是,這些偵聽器是同步的,不應執行耗時的任務。 - 將連接租用時間設置為 250 毫秒
- 將連接獲取時間設置為 50ms
4.2. FlexyPoolDataSource
配置
讓我們配置一個FlexyPoolDataSource
bean:
@Bean(initMethod = "start", destroyMethod = "stop")
public FlexyPoolDataSource<HikariDataSource> flexypoolDataSource() {
Configuration<HikariDataSource> configuration = flexypoolConfiguration();
return new FlexyPoolDataSource<>(
configuration,
new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Factory<>(5),
new RetryConnectionAcquiringStrategy.Factory<>(2));
}
這個FlexyPoolDataSource
在連接超時時向 Hikari 池添加了五個連接。如果池無法檢索連接,它還會最多重試連接兩次。
最後,我們可以通過調用FlexyPoolDataSource
來運行我們的應用程序:
@SpringBootApplication
public class FlexypoolDemoApplication {
private static FlexyPoolDataSource<HikariDataSource> poolDataSource;
public FlexypoolDemoApplication(FlexyPoolDataSource<HikariDataSource> poolDataSource) {
FlexypoolDemoApplication.poolDataSource = poolDataSource;
}
public static List<Employee> getEmployees() throws SQLException {
String SQL_QUERY = "select * from emp";
List<Employee> employees;
try (Connection con = poolDataSource.getConnection(); PreparedStatement pst = con.prepareStatement(SQL_QUERY); ResultSet rs = pst.executeQuery();) {
employees = new ArrayList<>();
Employee employee;
while (rs.next()) {
employee = new Employee();
employee.setEmpNo(rs.getInt("empno"));
employee.setEname(rs.getString("ename"));
employee.setJob(rs.getString("job"));
employee.setMgr(rs.getInt("mgr"));
employee.setHiredate(rs.getDate("hiredate"));
employee.setSal(rs.getInt("sal"));
employee.setComm(rs.getInt("comm"));
employee.setDeptno(rs.getInt("deptno"));
employees.add(employee);
}
}
return employees;
}
public static void main(String[] args) throws SQLException {
SpringApplication.run(FlexypoolDemoApplication.class, args);
List<Employee> employees = getEmployees();
System.out.println(employees);
}
}
5.結論
在本文中,我們學習瞭如何將 FlexyPool 與 Spring Boot 一起使用,以及如何使用 HikariCP 連接池使用 H2。
首先,我們看到瞭如何設置和配置 FlexyPool。然後我們也了解瞭如何監控其指標。
一如既往,完整的源代碼可在 GitHub 上獲得。