阅读完需:约 7 分钟
Jedis是Redis官方推荐的Java连接开发工具。要在Java开发中使用好Redis中间件,必须对Jedis熟悉才能写成漂亮的代码
开启远程连接
Redis 默认是不支持远程连接的,需要手动开启。
一共修改两个地方:
- 注释掉 bind: 127.0.0.1
- 开启密码校验,去掉 requirepass 的注释 改完之后,保存退出,启动 Redis。
首先创建一个普通的 Maven 项目。 项目创建成功后,添加 Jedis 依赖:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
然后创建一个测试方法。
public class MyJedis {
public static void main(String[] args) {
//1.构造一个 Jedis 对象,因为这里使用的默认端口 6379,所以不用配置端口
Jedis jedis = new Jedis("192.168.91.128");
// 2.密码认证
jedis.auth("javaboy");
// 3.测试是否连接成功
String ping = jedis.ping();
// 4.返回 pong 表示连接成功
System.out.println(ping);
}
}
对于 Jedis 而言,一旦连接上 Redis 服务端,剩下的操作都很容易了。 在 Jedis 中,由于方法的 API 和 Redis 的命令高度一致,所以,Jedis 中的方法见名知意,直接使用即可。
Jedis连接的优化
在实际应用中,Jedis 实例我们一般都是通过连接池来获取,由于 Jedis 对象不是线城安全的,所以,当我们使用 Jedis 对象时,从连接池获取 Jedis,使用完成之后,再还给连接池。
public class JedisPoolTest {
public static void main(String[] args) {
//1. 构造一个 Jedis 连接池
JedisPool pool = new JedisPool("192.168.91.128", 6379);
// 2. 从连接池中获取一个 Jedis 连接
Jedis jedis = pool.getResource();
// 3. Jedis 操作
String ping = jedis.ping();
System.out.println(ping);
// 4. 归还连接
jedis.close();
}
}
如果第三步抛出异常的话,会导致第四步无法执行,所以,我们要对代码进行改进,确保第四步能够执行。(添加try异常处理)
public class JedisPoolTest {
public static void main(String[] args) {
Jedis jedis= null;
try {
// 1.构造一个连接池
JedisPool jedisPool = new JedisPool("127.0.0.1");
//2.从连接池中获取一个Jedis连接
jedis = jedisPool.getResource();
//3.Jedis操作
String ping = jedis.ping();
System.out.println(ping);
} catch (Exception e) {
e.printStackTrace();
}finally {
//4.归还连接
jedis.close();
}
}
}
通过 finally 我们可以确保 jedis 一定被关闭。 利用 JDK1.7 中的 try-with-resource 特性,可以对上面的代码进行改造:(这会使try看起来很简介,其实本质是一样)
public class JedisPoolTest {
public static void main(String[] args) {
JedisPool pool = new JedisPool("192.168.91.128");
try(Jedis jedis = pool.getResource()) {
jedis.auth("javaboy");
String ping = jedis.ping();
System.out.println(ping);
}
}
}
这段代码的作用和上面的是一致的。
但是,上面这段代码无法实现强约束。我们可以做进一步的改进:
public interface CallWithJedis {
void call(Jedis jedis);
}
public class Redis {
private JedisPool pool;
public Redis() {
GenericObjectPoolConfig config = new GenericObjectPoolConfig();
//连接池最大空闲数
config.setMaxIdle(300);
//最大连接数
config.setMaxTotal(1000);
//连接最大等待时间,如果是 -1 表示没有限制
config.setMaxWaitMillis(30000);
// 在空闲时检查有效性
config.setTestOnBorrow(true);
/** * 1. Redis 地址 * 2. Redis 端口 * 3. 连接超时时间 * 4. 密码 */
pool = new JedisPool(config, "192.168.91.128", 6379, 30000, "javaboy");
}
public void execute(CallWithJedis callWithJedis) {
try (Jedis jedis = pool.getResource()) {
callWithJedis.call(jedis);
}
}
}
测试:
public static void main(String[] args) {
Redis redis = new Redis();
redis.execute(jedis -> {
System.out.println(jedis.ping());
});
}
GenericObjectPoolConfig 简介
本质上是”对象池”,即通过一定的规则来维护对象集合的容器;commos-pool在很多场景中,用来实现”连接池”/”任务worker池”等,大家常用的dbcp数据库连接池,也是基于commons-pool实现.
commons-pool实现思想非常简单,它主要的作用就是将”对象集合”池化,任何通过pool进行对象存取的操作,都会严格按照”pool配置”(比如池的大小)实时的创建对象/阻塞控制/销毁对象等.它在一定程度上,实现了对象集合的管理以及对象的分发.
pool基本参数
基本参数
- lifo
GenericObjectPool 提供了后进先出(LIFO)与先进先出(FIFO)两种行为模式的池。默认为true,即当池中有空闲可用的对象时,调用borrowObject方法会返回最近(后进
)的实例 - fairness
当从池中获取资源或者将资源还回池中时 是否使用java.util.concurrent.locks.ReentrantLock.ReentrantLock 的公平锁机制,默认为false
数量控制参数
- maxTotal
链接池中最大连接数,默认为8 - maxIdle
链接池中最大空闲的连接数,默认也为8 - minIdle
连接池中最少空闲的连接数,默认为0
超时参数
- maxWaitMillis
当连接池资源耗尽时,等待时间,超出则抛异常,默认为-1即永不超时 - blockWhenExhausted
当这个值为true的时候,maxWaitMillis参数才能生效。为false的时候,当连接池没资源,则立马抛异常。默认为true
test参数
- testOnCreate
默认false,create的时候检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取 - testOnBorrow
默认false,borrow的时候检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取 - testOnReturn
默认false,return的时候检测是有有效,如果无效则从连接池中移除,并尝试获取继续获取 - testWhileIdle
默认false,在evictor线程里头,当evictionPolicy.evict方法返回false时,而且testWhileIdle为true的时候则检测是否有效,如果无效则移除
检测参数
- timeBetweenEvictionRunsMillis
空闲链接检测线程检测的周期,毫秒数。如果为负值,表示不运行检测线程。默认为-1. - numTestsPerEvictionRun
在每次空闲连接回收器线程(如果有)运行时检查的连接数量,默认为3 - minEvictableIdleTimeMillis
连接空闲的最小时间,达到此值后空闲连接将可能会被移除。默认为1000L * 60L * 30L - softMinEvictableIdleTimeMillis
连接空闲的最小时间,达到此值后空闲链接将会被移除,且保留minIdle个空闲连接数。默认为-1. - evictionPolicyClassName
evict策略的类名,默认为org.apache.commons.pool2.impl.DefaultEvictionPolicy