Debugging Redis Connection Pool Blocking Issues in a Spring Backend Application

The article details a step‑by‑step investigation of a Spring‑based backend where API requests hung due to Redis connection pool misconfiguration, showing how thread dumps, jstack, and Arthas were used to pinpoint blocking in Jedis pool acquisition, and provides corrected configuration and proper connection handling recommendations.

Top Architect
Top Architect
Top Architect
Debugging Redis Connection Pool Blocking Issues in a Spring Backend Application

The author, a senior architect, describes a week‑long outage in an internal sandbox where all APIs became unresponsive and the application appeared to be dead. Initial checks showed no errors in the database or Redis, leading to suspicion of the sandbox environment itself.

Using SSH, the author ran top and identified the most resource‑intensive threads with top -H -p 12798. A jstack of the process revealed several threads stuck in lock states, but no business‑level code was visible.

Further debugging involved remote debugging of the Tomcat process. After setting breakpoints at the AOP layer, the author discovered that the application hung while executing a Redis command. Inspection of the Jedis pool code showed that pool.getResource() eventually called internalPool.borrowObject(), which could block indefinitely when borrowMaxWaitMillis was negative.

The root cause was a missing maxWaitMillis configuration in the Redis pool, causing threads to wait forever for a connection. This was confirmed by thread dumps from Arthas showing many http-nio threads in a waiting state.

To fix the issue, the author added explicit pool configuration:

JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxWaitMillis(2000);
... // other settings
jedisConnectionFactory.afterPropertiesSet();

After restarting the service, the problem persisted until the pool timeout was correctly set, after which the API responses returned to normal.

The article also warns against using stringRedisTemplate.getConnectionFactory().getConnection() directly, recommending the use of

stringRedisTemplate.execute(new RedisCallback(){ public Cursor doInRedis(RedisConnection connection) throws DataAccessException { return connection.scan(options); } })

or explicitly releasing connections with RedisConnectionUtils.releaseConnection(conn, factory). Additionally, it advises against using the KEYS command in production and stresses proper pool sizing.

In summary, the investigation demonstrates how thorough thread analysis, proper configuration of Redis connection pools, and correct usage of Spring's Redis utilities can prevent silent deadlocks and improve backend reliability.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DebuggingredisspringConnection PoolJedis
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.