Why Your JedisPool Keeps Recreating Connections and How to Fix It in Spring Boot
This article investigates why a Spring Boot application using JedisPool experiences high connection‑acquisition latency, analyzes the Evictor logic and mis‑configured pool parameters, and presents a custom configuration solution that stabilizes the pool and eliminates repeated connection creation and destruction.
Background
The author previously wrote an article on troubleshooting high Redis latency by configuring a stable connection pool. Recent load‑testing still shows requests blocked while acquiring connections from JedisPool, leading to overall request timeouts.
Problem 1: Persistent Jedis Connection Timeouts
Even with a pool configured as spring.redis.jedis.pool.max-active=500, max-idle=500, min-idle=500, and heartbeat checks enabled, the maximum wait time for a connection remains above 900 ms. Metrics show large createdCount and destroyedCount values, indicating frequent connection recreation.
Analysis of Pool Parameters
spring.redis.jedis.pool.max-active=500 // 4 servers × 500 = 2000 < 30000 (Redis limit)</code>
<code>spring.redis.jedis.pool.max-idle=500</code>
<code>spring.redis.jedis.pool.min-idle=500 // stable pool size</code>
<code>spring.redis.jedis.pool.test-while-idle=true // periodic health check</code>
<code>spring.redis.jedis.pool.time-between-eviction-runs-millis=30000</code>
<code>spring.redis.jedis.pool.num-tests-per-eviction-run=-1 // test all idle connections each run</code>
<code>spring.redis.jedis.pool.min-evictable-idle-time-millis=-1 // prevent idle‑time based evictionDespite these settings, the destroyedCount and destroyedByEvictorCount are identical, meaning the Evictor is responsible for all connection removals.
Evictor Logic
The core Evictor code resides in org.apache.commons.pool2.impl.GenericObjectPool#evict. It removes connections when either the idle time exceeds a threshold or the Redis heartbeat fails.
Is Idle Timeout the Cause?
Configuration shows min-evictable-idle-time-millis is set to Long.MAX_VALUE in the article, but the actual default in JedisPoolConfig is 60000 ms, causing connections idle for more than 60 s to be evicted.
Is Redis Heartbeat Failure the Cause?
Local ping tests show normal latency, so heartbeat failures are unlikely.
Root Cause
The Evictor runs every 30 s, evicting idle connections after 60 s, and JedisPool uses LIFO ordering by default, which repeatedly destroys and recreates the same connections.
Why LIFO Matters
With LIFO, returned connections are placed at the head of the pool, while borrowed connections are taken from the tail, leading to a cycle of Create → Idle → minIdle(60s) → Destroy → Create.
Failed Work‑arounds
Upgrading Spring Boot does not expose min-evictable-idle-time-millis in RedisProperties.Pool.
Switching the pool to FIFO via setLifo(false) still suffers from the same missing configuration.
Disabling or lengthening the Evictor interval removes idle‑based evictions but also disables automatic reconnection after Redis failures.
Effective Solution (Solution 4)
Implement a custom JedisClientConfigurationBuilderCustomizer to inject the missing parameters ( min-evictable-idle-time-millis, num-tests-per-eviction-run, lifo, etc.) into the pool configuration.
public JedisPoolConfig jedisPoolConfig(RedisProperties.Pool pool) {</code>
<code> JedisPoolConfig config = new JedisPoolConfig();</code>
<code> config.setMaxTotal(pool.getMaxActive());</code>
<code> config.setMaxIdle(pool.getMaxIdle());</code>
<code> config.setMinIdle(pool.getMinIdle());</code>
<code> if (pool.getTimeBetweenEvictionRuns() != null) {</code>
<code> config.setTimeBetweenEvictionRunsMillis(pool.getTimeBetweenEvictionRuns().toMillis());</code>
<code> }</code>
<code> if (pool.getMaxWait() != null) {</code>
<code> config.setMaxWaitMillis(pool.getMaxWait().toMillis());</code>
<code> }</code>
<code> // custom properties injected here</code>
<code> return config;</code>
<code>}Verification
After applying the customizer, the pool remains stable: connection‑acquisition latency drops from >900 ms to a few tens of milliseconds, and the nightly load‑test timeout disappears.
Summary of Steps
Configure core pool properties supported by Spring Boot.
Implement a JedisClientConfigurationBuilderCustomizer to add unsupported properties such as min-evictable-idle-time-millis, num-tests-per-eviction-run, and lifo.
Validate that the pool no longer destroys and recreates connections under normal load.
References: [1] Spring Boot RedisProperties source [2] Jedis issue discussing connection recreation [3] GitHub issue for adding more Jedis pool properties
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Alibaba Cloud Developer
Alibaba's official tech channel, featuring all of its technology innovations.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
