目录
1、JedisPool的应用
1.1 基本应用
1.2 封装应用
1.3 增加超时重试
2、JedisPool配置
2.1 工厂配置
2.2 资源池配置
Jedis提供了连接池JedisPool。由于Jedis对象不是线程安全的,所以一般会从连接池中取出一个Jedis对象独占,使用完毕后再归还给连接池。
maven依赖:
redis.clients
jedis
3.1.0
资源池简单应用代码示例:
// 获取连接池
JedisPool pool = new JedisPool();
// 从资源池中拿出可以链接对象
// 用try-with-resource自动调用close方法归还资源
try(Jedis jedis = pool.getResource();) {
// 应用程序执行操作
}
上述写法,如果使用者没有使用try-with-resource并且忘记了归还资源,可以对JedisPool做一层封装,将归还资源的操作封装起来。
1、资源池:
public class RedisPool {
private JedisPool pool;
public RedisPool() {
this.pool = new JedisPool();
}
/**
* 执行任务
*
* @param callable
*/
public void execute(RedisCallable callable) {
try(Jedis jedis = pool.getResource()) {
callable.call(jedis);
}
}
}
2、回调接口:
public interface RedisCallable {
/**
* 回调方法,执行需要执行的任务
*
* @param jedis jedis
*/
void call(Jedis jedis);
}
3、使用:
public class RedisMain {
public static void main(String[] args) {
RedisPool pool = new RedisPool();
pool.execute((jedis) -> {
System.out.println(jedis.get("key"));
});
}
}
网络抖动情况下,需要增加超时重试机制,在捕获到JedisConnectionException时可以进行重试。
可以按如下方式改造资源池:
public class RedisPool {
/**
* 最大重试次数
*/
private static final int MAX_RETRY = 3;
private JedisPool pool;
public RedisPool() {
this.pool = new JedisPool();
}
/**
* 执行任务
*
* @param callable
*/
public void execute(RedisCallable callable) {
int count = 0;
try (Jedis jedis = pool.getResource()) {
execute(callable, jedis, count);
}
}
private void execute(RedisCallable callable, Jedis jedis, int count) {
try {
callable.call(jedis);
} catch (JedisConnectionException e) {
if (count < MAX_RETRY) {
execute(callable, jedis, ++count);
} else {
throw e;
}
}
}
}
JedisPool入参最多的构造器:
public JedisPool(final GenericObjectPoolConfig poolConfig, final String host, int port,
final int connectionTimeout, final int soTimeout, final String password, final int database,
final String clientName) {
super(poolConfig, new JedisFactory(host, port, connectionTimeout, soTimeout, password,
database, clientName));
}
上述参数可以分成两部分:资源池配置,以及工厂配置。
JedisFactory的主要功能为管理(创建,关闭,验证)redis的连接客户端jedis。从连接池获取jedis连接资源,实际上看是从JedisPool的父类pool中获取,而pool又委托给JedisFactory,最后由JedisFactory创建redis连接客户端jedis。
资源池JedisPool使用GenericObjectPool的实例来传入配置,而GenericObjectPool是BaseGenericObjectPool的子类。
核心参数:
空闲连接资源检测相关:
空闲连接资源驱逐相关:
BaseGenericObjectPool的配置如下:
private volatile int maxTotal =
GenericKeyedObjectPoolConfig.DEFAULT_MAX_TOTAL;
private volatile boolean blockWhenExhausted =
BaseObjectPoolConfig.DEFAULT_BLOCK_WHEN_EXHAUSTED;
private volatile long maxWaitMillis =
BaseObjectPoolConfig.DEFAULT_MAX_WAIT_MILLIS;
private volatile boolean lifo = BaseObjectPoolConfig.DEFAULT_LIFO;
private final boolean fairness;
private volatile boolean testOnCreate =
BaseObjectPoolConfig.DEFAULT_TEST_ON_CREATE;
private volatile boolean testOnBorrow =
BaseObjectPoolConfig.DEFAULT_TEST_ON_BORROW;
private volatile boolean testOnReturn =
BaseObjectPoolConfig.DEFAULT_TEST_ON_RETURN;
private volatile boolean testWhileIdle =
BaseObjectPoolConfig.DEFAULT_TEST_WHILE_IDLE;
private volatile long timeBetweenEvictionRunsMillis =
BaseObjectPoolConfig.DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
private volatile int numTestsPerEvictionRun =
BaseObjectPoolConfig.DEFAULT_NUM_TESTS_PER_EVICTION_RUN;
private volatile long minEvictableIdleTimeMillis =
BaseObjectPoolConfig.DEFAULT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private volatile long softMinEvictableIdleTimeMillis =
BaseObjectPoolConfig.DEFAULT_SOFT_MIN_EVICTABLE_IDLE_TIME_MILLIS;
private volatile EvictionPolicy evictionPolicy;
private volatile long evictorShutdownTimeoutMillis =
BaseObjectPoolConfig.DEFAULT_EVICTOR_SHUTDOWN_TIMEOUT_MILLIS;
GenericObjectPool的配置如下:
/**
* The default value for the {@code maxTotal} configuration attribute.
* @see GenericObjectPool#getMaxTotal()
*/
public static final int DEFAULT_MAX_TOTAL = 8;
/**
* The default value for the {@code maxIdle} configuration attribute.
* @see GenericObjectPool#getMaxIdle()
*/
public static final int DEFAULT_MAX_IDLE = 8;
/**
* The default value for the {@code minIdle} configuration attribute.
* @see GenericObjectPool#getMinIdle()
*/
public static final int DEFAULT_MIN_IDLE = 0;
private int maxTotal = DEFAULT_MAX_TOTAL;
private int maxIdle = DEFAULT_MAX_IDLE;
private int minIdle = DEFAULT_MIN_IDLE;