Merge pull request #26326 from weixsun
* pr/26326: Polish "Enable Redis connection pool if commons-pool2 is available" Enable Redis connection pool if commons-pool2 is available Closes gh-26326
This commit is contained in:
commit
de350a0596
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -76,7 +76,7 @@ class JedisConnectionConfiguration extends RedisConnectionConfiguration {
|
|||
ObjectProvider<JedisClientConfigurationBuilderCustomizer> builderCustomizers) {
|
||||
JedisClientConfigurationBuilder builder = applyProperties(JedisClientConfiguration.builder());
|
||||
RedisProperties.Pool pool = getProperties().getJedis().getPool();
|
||||
if (pool != null) {
|
||||
if (isPoolEnabled(pool)) {
|
||||
applyPooling(pool, builder);
|
||||
}
|
||||
if (StringUtils.hasText(getProperties().getUrl())) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -104,10 +104,10 @@ class LettuceConnectionConfiguration extends RedisConnectionConfiguration {
|
|||
}
|
||||
|
||||
private LettuceClientConfigurationBuilder createBuilder(Pool pool) {
|
||||
if (pool == null) {
|
||||
return LettuceClientConfiguration.builder();
|
||||
if (isPoolEnabled(pool)) {
|
||||
return new PoolBuilderFactory().createBuilder(pool);
|
||||
}
|
||||
return new PoolBuilderFactory().createBuilder(pool);
|
||||
return LettuceClientConfiguration.builder();
|
||||
}
|
||||
|
||||
private LettuceClientConfigurationBuilder applyProperties(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,12 +22,14 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool;
|
||||
import org.springframework.data.redis.connection.RedisClusterConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisNode;
|
||||
import org.springframework.data.redis.connection.RedisPassword;
|
||||
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
@ -40,6 +42,9 @@ import org.springframework.util.StringUtils;
|
|||
*/
|
||||
abstract class RedisConnectionConfiguration {
|
||||
|
||||
private static final boolean COMMONS_POOL2_AVAILABLE = ClassUtils.isPresent("org.apache.commons.pool2.ObjectPool",
|
||||
RedisConnectionConfiguration.class.getClassLoader());
|
||||
|
||||
private final RedisProperties properties;
|
||||
|
||||
private final RedisSentinelConfiguration sentinelConfiguration;
|
||||
|
@ -122,6 +127,11 @@ abstract class RedisConnectionConfiguration {
|
|||
return this.properties;
|
||||
}
|
||||
|
||||
protected boolean isPoolEnabled(Pool pool) {
|
||||
Boolean enabled = pool.getEnabled();
|
||||
return (enabled != null) ? enabled : COMMONS_POOL2_AVAILABLE;
|
||||
}
|
||||
|
||||
private List<RedisNode> createSentinels(RedisProperties.Sentinel sentinel) {
|
||||
List<RedisNode> nodes = new ArrayList<>();
|
||||
for (String node : sentinel.getNodes()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -233,6 +233,12 @@ public class RedisProperties {
|
|||
*/
|
||||
public static class Pool {
|
||||
|
||||
/**
|
||||
* Whether to enable the pool. Enabled automatically if "commons-pool2" is
|
||||
* available.
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* Maximum number of "idle" connections in the pool. Use a negative value to
|
||||
* indicate an unlimited number of idle connections.
|
||||
|
@ -265,6 +271,14 @@ public class RedisProperties {
|
|||
*/
|
||||
private Duration timeBetweenEvictionRuns;
|
||||
|
||||
public Boolean getEnabled() {
|
||||
return this.enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(Boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public int getMaxIdle() {
|
||||
return this.maxIdle;
|
||||
}
|
||||
|
@ -396,16 +410,12 @@ public class RedisProperties {
|
|||
/**
|
||||
* Jedis pool configuration.
|
||||
*/
|
||||
private Pool pool;
|
||||
private final Pool pool = new Pool();
|
||||
|
||||
public Pool getPool() {
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
public void setPool(Pool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -421,7 +431,7 @@ public class RedisProperties {
|
|||
/**
|
||||
* Lettuce pool configuration.
|
||||
*/
|
||||
private Pool pool;
|
||||
private final Pool pool = new Pool();
|
||||
|
||||
private final Cluster cluster = new Cluster();
|
||||
|
||||
|
@ -437,10 +447,6 @@ public class RedisProperties {
|
|||
return this.pool;
|
||||
}
|
||||
|
||||
public void setPool(Pool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public Cluster getCluster() {
|
||||
return this.cluster;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
*
|
||||
* @author Mark Paluch
|
||||
* @author Stephane Nicoll
|
||||
* @author Weix Sun
|
||||
*/
|
||||
@ClassPathExclusions("lettuce-core-*.jar")
|
||||
class RedisAutoConfigurationJedisTests {
|
||||
|
@ -142,6 +143,16 @@ class RedisAutoConfigurationJedisTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationDisabledPool() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.jedis.pool.enabled:false")
|
||||
.run((context) -> {
|
||||
JedisConnectionFactory cf = context.getBean(JedisConnectionFactory.class);
|
||||
assertThat(cf.getHostName()).isEqualTo("foo");
|
||||
assertThat(cf.getClientConfiguration().isUsePooling()).isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationWithTimeoutAndConnectTimeout() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.timeout:250",
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.data.redis;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RedisAutoConfiguration} when commons-pool2 is not on the classpath.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@ClassPathExclusions("commons-pool2-*.jar")
|
||||
public class RedisAutoConfigurationLettuceWithoutCommonsPool2Tests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void poolWithoutCommonsPool2IsDisabledByDefault() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo").run((context) -> {
|
||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||
assertThat(cf.getHostName()).isEqualTo("foo");
|
||||
assertThat(ReflectionTestUtils.getField(cf, "clientConfiguration"))
|
||||
.isNotInstanceOf(LettucePoolingClientConfiguration.class);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -31,6 +31,7 @@ import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.data.redis.RedisProperties.Pool;
|
||||
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
|
@ -65,6 +66,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
|||
* @author Stephane Nicoll
|
||||
* @author Alen Turkovic
|
||||
* @author Scott Frederick
|
||||
* @author Weix Sun
|
||||
*/
|
||||
class RedisAutoConfigurationTests {
|
||||
|
||||
|
@ -155,7 +157,21 @@ class RedisAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationWithPool() {
|
||||
void testRedisConfigurationUsePoolByDefault() {
|
||||
Pool defaultPool = new RedisProperties().getLettuce().getPool();
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo").run((context) -> {
|
||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||
assertThat(cf.getHostName()).isEqualTo("foo");
|
||||
GenericObjectPoolConfig<?> poolConfig = getPoolingClientConfiguration(cf).getPoolConfig();
|
||||
assertThat(poolConfig.getMinIdle()).isEqualTo(defaultPool.getMinIdle());
|
||||
assertThat(poolConfig.getMaxIdle()).isEqualTo(defaultPool.getMaxIdle());
|
||||
assertThat(poolConfig.getMaxTotal()).isEqualTo(defaultPool.getMaxActive());
|
||||
assertThat(poolConfig.getMaxWaitMillis()).isEqualTo(defaultPool.getMaxWait().toMillis());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationWithCustomPoolSettings() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.lettuce.pool.min-idle:1",
|
||||
"spring.redis.lettuce.pool.max-idle:4", "spring.redis.lettuce.pool.max-active:16",
|
||||
"spring.redis.lettuce.pool.max-wait:2000", "spring.redis.lettuce.pool.time-between-eviction-runs:30000",
|
||||
|
@ -172,6 +188,17 @@ class RedisAutoConfigurationTests {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationDisabledPool() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.lettuce.pool.enabled:false")
|
||||
.run((context) -> {
|
||||
LettuceConnectionFactory cf = context.getBean(LettuceConnectionFactory.class);
|
||||
assertThat(cf.getHostName()).isEqualTo("foo");
|
||||
assertThat(ReflectionTestUtils.getField(cf, "clientConfiguration"))
|
||||
.isNotInstanceOf(LettucePoolingClientConfiguration.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRedisConfigurationWithTimeoutAndConnectTimeout() {
|
||||
this.contextRunner.withPropertyValues("spring.redis.host:foo", "spring.redis.timeout:250",
|
||||
|
|
|
@ -46,7 +46,7 @@ If you use Jedis, `JedisClientConfigurationBuilderCustomizer` is also available.
|
|||
|
||||
If you add your own `@Bean` of any of the auto-configured types, it replaces the default (except in the case of `RedisTemplate`, when the exclusion is based on the bean name, `redisTemplate`, not its type).
|
||||
|
||||
A pooled connection factory is auto-configured if `commons-pool2` is on the classpath and at least one `Pool` option of {spring-boot-autoconfigure-module-code}/data/redis/RedisProperties.java[`RedisProperties`] is set.
|
||||
By default, a pooled connection factory is auto-configured if `commons-pool2` is on the classpath.
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue