最近在做一个服务的过程中,需要从redis中读取热点数据,限制的超时时间不超过10ms,在1000并发压测的情况下,平均每个请求的耗时为4~5ms,但是和上游联调调用的时候总会很多请求超时,让人胆战心惊,百思不得其解,那么看一下Spring中JedisPoolConfig的配置:
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="600" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="600" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
配置了maxIdle最大空闲连接数,但是没有配置minIdle(最小空闲连接数),与其说是最小空闲连接数,不如说是"至少需要保持的空闲连接数",那么在初始化连接池的过程中就会建立minIdle个连接,在使用连接的过程中,如果连接数超过了minIdle,那么继续建立连接,但是不超时maxIdle。minIdle的默认值如下代码所示:
public class GenericObjectPoolConfig extends BaseObjectPoolConfig {
public static final int DEFAULT_MAX_TOTAL = 8;
public static final int DEFAULT_MAX_IDLE = 8;
public static final int DEFAULT_MIN_IDLE = 0;
private int maxTotal = 8;
private int maxIdle = 8;
private int minIdle = 0;
....
}
可见minIdel的默认值为0,因此,在一段时间的间隔后,连接就被回收了,导致再次请求的时候需要重新建立连接,传输数据,这就是耗时问题所在,解决方案,加上minIdle配置即可:
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="600" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="600" />
<!-- 最小空连接数 -->
<property name="minIdle" value="450" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
<!--定时对线程池中空闲的链接进行validateObject校验 -->
<property name="testWhileIdle" value="true" />
<!--在进行returnObject对返回的connection进行validateObject校验 -->
<property name="testOnReturn" value="true" />
</bean>
Author:忆之独秀
Email:leaguenew@qq.com
注明出处:https://blog.csdn.net/lavorange/article/details/84448910