Add metrics support for idle jdbc connections
See gh-17504
This commit is contained in:
committed by
Stephane Nicoll
parent
808b373def
commit
9acc02b5cc
@@ -38,6 +38,7 @@ import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
*
|
||||
* @author Jon Schneider
|
||||
* @author Phillip Webb
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class DataSourcePoolMetrics implements MeterBinder {
|
||||
@@ -68,6 +69,7 @@ public class DataSourcePoolMetrics implements MeterBinder {
|
||||
bindPoolMetadata(registry, "active", DataSourcePoolMetadata::getActive);
|
||||
bindPoolMetadata(registry, "max", DataSourcePoolMetadata::getMax);
|
||||
bindPoolMetadata(registry, "min", DataSourcePoolMetadata::getMin);
|
||||
bindPoolMetadata(registry, "idle", DataSourcePoolMetadata::getIdle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.apache.commons.dbcp2.BasicDataSource;
|
||||
* {@link DataSourcePoolMetadata} for an Apache Commons DBCP2 {@link DataSource}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<BasicDataSource> {
|
||||
@@ -57,4 +58,9 @@ public class CommonsDbcp2DataSourcePoolMetadata extends AbstractDataSourcePoolMe
|
||||
return getDataSource().getDefaultAutoCommit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIdle() {
|
||||
return getDataSource().getNumIdle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import javax.sql.DataSource;
|
||||
* {@link DataSource} implementations.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public interface DataSourcePoolMetadata {
|
||||
@@ -49,6 +50,16 @@ public interface DataSourcePoolMetadata {
|
||||
*/
|
||||
Integer getActive();
|
||||
|
||||
/**
|
||||
* Return the number of established but idle connections. Can also return {@code null}
|
||||
* if that information is not available.
|
||||
* @return the number of established but idle connections or {@code null}
|
||||
* @since 2.2.0
|
||||
*/
|
||||
default Integer getIdle() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the maximum number of active connections that can be allocated at the same
|
||||
* time or {@code -1} if there is no limit. Can also return {@code null} if that
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.boot.jdbc.metadata;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
@@ -27,6 +29,7 @@ import org.springframework.beans.DirectFieldAccessor;
|
||||
* {@link DataSourcePoolMetadata} for a Hikari {@link DataSource}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<HikariDataSource> {
|
||||
@@ -45,6 +48,16 @@ public class HikariDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIdle() {
|
||||
HikariPool pool = getHikariPool();
|
||||
if (Objects.nonNull(pool)) {
|
||||
return pool.getIdleConnections();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private HikariPool getHikariPool() {
|
||||
return (HikariPool) new DirectFieldAccessor(getDataSource()).getPropertyValue("pool");
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.apache.tomcat.jdbc.pool.DataSource;
|
||||
* {@link DataSourcePoolMetadata} for a Tomcat DataSource.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata<DataSource> {
|
||||
@@ -57,4 +58,9 @@ public class TomcatDataSourcePoolMetadata extends AbstractDataSourcePoolMetadata
|
||||
return getDataSource().isDefaultAutoCommit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getIdle() {
|
||||
return getDataSource().getNumIdle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
*
|
||||
* @param <D> the data source pool metadata type
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
*/
|
||||
abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourcePoolMetadata<?>> {
|
||||
|
||||
@@ -67,6 +68,11 @@ abstract class AbstractDataSourcePoolMetadataTests<D extends AbstractDataSourceP
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void getIdle() {
|
||||
assertThat(getDataSourceMetadata().getIdle()).isEqualTo(Integer.valueOf(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getPoolSizeTwoConnections() {
|
||||
final JdbcTemplate jdbcTemplate = new JdbcTemplate(getDataSourceMetadata().getDataSource());
|
||||
|
||||
@@ -19,6 +19,9 @@ package org.springframework.boot.jdbc.metadata;
|
||||
import org.apache.commons.dbcp2.BasicDataSource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
@@ -83,6 +86,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests
|
||||
BasicDataSource dataSource = createDataSource();
|
||||
dataSource.setMinIdle(minSize);
|
||||
dataSource.setMaxTotal(maxSize);
|
||||
|
||||
this.initPool(dataSource);
|
||||
|
||||
return new CommonsDbcp2DataSourcePoolMetadata(dataSource);
|
||||
}
|
||||
|
||||
@@ -90,4 +96,9 @@ class CommonsDbcp2DataSourcePoolMetadataTests
|
||||
return initializeBuilder().type(BasicDataSource.class).build();
|
||||
}
|
||||
|
||||
private void initPool(BasicDataSource dataSource) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,16 @@ package org.springframework.boot.jdbc.metadata;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link HikariDataSourcePoolMetadata}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Artsiom Yudovin
|
||||
*/
|
||||
public class HikariDataSourcePoolMetadataTests
|
||||
extends AbstractDataSourcePoolMetadataTests<HikariDataSourcePoolMetadata> {
|
||||
@@ -54,7 +58,15 @@ public class HikariDataSourcePoolMetadataTests
|
||||
HikariDataSource dataSource = initializeBuilder().type(HikariDataSource.class).build();
|
||||
dataSource.setMinimumIdle(minSize);
|
||||
dataSource.setMaximumPoolSize(maxSize);
|
||||
|
||||
this.initPool(dataSource);
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private void initPool(HikariDataSource dataSource) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.boot.jdbc.metadata;
|
||||
|
||||
import org.apache.tomcat.jdbc.pool.DataSource;
|
||||
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
@@ -58,7 +61,15 @@ public class TomcatDataSourcePoolMetadataTests
|
||||
// Avoid warnings
|
||||
dataSource.setInitialSize(minSize);
|
||||
dataSource.setMaxIdle(maxSize);
|
||||
|
||||
this.initPool(dataSource);
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private void initPool(DataSource dataSource) {
|
||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
||||
jdbcTemplate.execute((ConnectionCallback<Void>) (connection) -> null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user