1、获取jedis实例时,实际上可能有两类错误。
一类是pool.getReource(),得不到可用的jedis实例;
另一类是jedis.set/get时出错也会抛出异常;
为了实现区分,所以根据instance是否为null来实现,如果为空就证明instance根本就没初始化,也就不用return给pool;如果instance不为null,则证明是需要返还给pool的;
2、在instance出错时,必须调用returnBrokenResource返还给pool,否则下次通过getResource得到的instance的缓冲区可能还存在数据,出现问题!
-------------------------------------------------
JedisPool的配置参数大部分是由JedisPoolConfig的对应项来赋值的。
jedis包括2.4.1,2.5.1等高版本的JedisPoolConfig没有maxActive属性,不能按照网上那些方式去配置redis了,网上大部分搜索出来的redis配置都是基于旧版本的jedis,在jedis新版本,JedisPoolConfig没有maxActive属性,JedisPoolConfig没有maxWait属性,以及被替换成其他的命名。
其实高版本的jedis使用了org.apache.commons.pool2.impl.GenericObjectPoolConfig。dbcp的修改日志显示:change "maxActive" -> "maxTotal" and "maxWait" -> "maxWaitMillis" in all examples.所以高版本jedis配置JedisPoolConfig的maxActive,maxWait应该为:
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.pool.maxIdle}" />
<property name="maxTotal" value="${redis.pool.maxActive}" />
<property name="maxWaitMillis" value="${redis.pool.maxWait}" />
<property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />
<property name="testOnReturn" value="${redis.pool.testOnReturn}" />
</bean>
maxActive:连接池的最大数据库连接数。设为0表示无限制,如果是jedis 2.4以后用redis.maxTotal.控制一个pool可分配多少个jedis实例,通过pool.getResource()来获取;如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted。
maxTotal:控制一个pool可分配多少个jedis实例,用来替换上面的redis.maxActive,如果是jedis 2.4以后用该属性
maxIdle:控制一个pool最多有多少个状态为idle(空闲)的jedis实例;
whenExhaustedAction:表示当pool中的jedis实例都被allocated完时,pool要采取的操作;默认有三种。
WHEN_EXHAUSTED_FAIL --> 表示无jedis实例时,直接抛出NoSuchElementException;
WHEN_EXHAUSTED_BLOCK --> 则表示阻塞住,或者达到maxWait时抛出JedisConnectionException;
WHEN_EXHAUSTED_GROW --> 则表示新建一个jedis实例,也就说设置的maxActive无用;
maxWait:高版本用maxWaitMillis。表示当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
testOnBorrow:在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
testOnReturn:在return给pool时,是否提前进行validate操作;
testWhileIdle:如果为true,表示有一个idle object evitor线程对idle object进行扫描,如果validate失败,此object会被从pool中drop掉;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
timeBetweenEvictionRunsMillis:表示idle object evitor两次扫描之间要sleep的毫秒数;
numTestsPerEvictionRun:表示idle object evitor每次扫描的最多的对象数;
minEvictableIdleTimeMillis:表示一个对象至少停留在idle状态的最短时间,然后才能被idle object evitor扫描并驱逐;这一项只有在timeBetweenEvictionRunsMillis大于0时才有意义;
softMinEvictableIdleTimeMillis:在minEvictableIdleTimeMillis基础上,加入了至少minIdle个对象已经在pool里面了。如果为-1,evicted不会根据idle time驱逐任何对象。如果minEvictableIdleTimeMillis>0,则此项设置无意义,且只有在timeBetweenEvictionRunsMillis大于0时才有意义;
lifo:borrowObject返回对象时,是采用DEFAULT_LIFO(last in first out,即类似cache的最频繁使用队列),如果为False,则表示FIFO队列;
其中JedisPoolConfig对一些参数的默认设置如下:
testWhileIdle=true
minEvictableIdleTimeMills=60000
timeBetweenEvictionRunsMillis=30000
numTestsPerEvictionRun=-1
补充文章JedisPoolConfig配置:
spring.redis.database: 0
spring.redis.host: 130.31.0.29
spring.redis.port: 1111
spring.redis.password: 222222
spring.redis.timeout: 100000
spring.redis.jedis.pool.maxTotal: 1000
spring.redis.jedis.pool.maxWaitMillis: 30000
spring.redis.jedis.pool.minIdle: 200
spring.redis.jedis.pool.maxIdle: 300
package com.config;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* jedis的配置类
*
* @version:1.0
* @author
* @date
*/
@Configuration
public class JedisConfig extends CachingConfigurerSupport {
private static final Logger log = Logger.getLogger(JedisConfig.class);
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private String timeout;
@Value("${spring.redis.jedis.pool.minIdle}")
private int minIdle;
@Value("${spring.redis.jedis.pool.maxIdle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.maxTotal}")
private int maxTotal;
@Value("${spring.redis.jedis.pool.maxWaitMillis}")
private String maxWaitMillis;
@Value("${spring.redis.password}")
private String password;
@Bean
public JedisPool redisPoolFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxWaitMillis(Long.parseLong(maxWaitMillis));
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port,
Integer.valueOf(timeout.substring(0, timeout.length() - 2)), password);
log.info("jedisPool created successfully------------------");
return jedisPool;
}
}