我开发了一个与 db2 对话的 Spring Boot Restfull 应用程序。
我使用 Hikari 数据源进行良好的池处理(也许)
密码是从安全系统获取的,对于每个获取连接,我设置从保险箱收到的密码。
我为每个连接设置密码的原因是因为密码可以在保险箱中每周一次在未知时间更改,所以我必须在连接之前获取新密码并将其设置为现有密码。
问题是 Hikari 会保留旧密码,即使池是空的并且我给出了新密码
知道如何更改每个获取连接的密码吗?
这是 Hikari 的配置文件
#maximum number of milliseconds that a client will wait for a connection
spring.datasource.connectionTimeout=20000
#minimum number of idle connections maintained by HikariCP in a connection pool
spring.datasource.minimumIdle=0
#maximum pool size
spring.datasource.maximumPoolSize=100
#maximum idle time for connection
spring.datasource.idleTimeout=30000
# maximum lifetime in milliseconds of a connection in the pool after it is closed.
spring.datasource.maxLifetime=0
#default auto-commit behavior.
spring.datasource.autocommit=true
spring.datasource.poolName=db2Pool
创建数据源
@Bean("dataSourceMF")
@Order(PriorityOrdered.HIGHEST_PRECEDENCE)
public DataSource dataSourceMF() {
PasswordsMessage passwordsMessage = passwordApi.getPassword("username");
String userPassword = passwordsMessage.getPassword();
Properties configProps = new Properties();
configProps.put("poolName", poolName);
configProps.put("jdbcUrl", db2Url);
configProps.put("driverClassName", db2Driver);
configProps.put("username", db2User);
configProps.put("catalog", db2Catalog);
configProps.put("maximumPoolSize", maximumPoolSize);
configProps.put("minimumIdle", minimumIdle);
configProps.put("connectionTimeout", connectionTimeout);
configProps.put("idleTimeout", idleTimeout);
configProps.put("autoCommit", autoCommit);
configProps.put("dataSource.prepStmtCacheSize", 250);
configProps.put("dataSource.prepStmtCacheSqlLimit", 2048);
configProps.put("dataSource.cachePrepStmts", Boolean.TRUE);
configProps.put("dataSource.useServerPrepStmts", Boolean.TRUE);
configProps.put("password", userPassword);
HikariConfig hc = new HikariConfig(configProps);
dataSource = new HikariDataSource(hc);
return dataSource;
}
建立连接
public Connection getConnection() throws SQLException, Exception {
PasswordsMessage passwordsMessage = passwordApi.getPassword("username");
String userPassword = passwordsMessage.getPassword();
try {
dataSource.setPassword(userPassword);
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
}
pom.xml
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.4.7</version>
</dependency>
首先,您必须找到密码重置的确切时间。在我的例子中,我们使用 AWS SecretManager 与 RDS 绑定,密码根据 cron 表达式在每月第一天 00:00 自动轮换。我创建了调度程序,它在密码自动旋转并在 hikari 中更新后立即获取密码。
@Scheduled(cron = "2 0 1 * *"")
public void autoRotatePassword() throws Exception {
HikariDataSource datasource = (HikariDataSource) dataSource();
HikariConfigMXBean hikariConfigMXBean = datasource.getHikariConfigMXBean();
LOGGER.info(String.format("Start refreshing passowrd in %s...", hikariConfigMXBean.getPoolName()));
hikariConfigMXBean.setPassword(getPassword());
HikariPoolMXBean pool = datasource.getHikariPoolMXBean();
if (pool != null) {
pool.softEvictConnections(); // Close unused cnxns & mark open ones for disposal
pool.resumePool(); // Re-enable connections
}
}
其中 getPassword() 包含从 SecretManager 获取密码的机制。