Redis 的 Java 客户端
1. 开启远程连接
因为 Redis 默认的是不支持远程连接,需要我们手动配置一下 redis.conf
这个配置文件:
注释掉 bing:127.0.0.1
开启密码校验,去掉 requirepass 的注释
改过之后,保存退出,启动 Redis 。
2. Jedis
2.1 基本使用
Jedis 的 GitHub 的地址:https://github.com/xetorthio/jedis
首先创建一个普通的 Maven 项目,添加 Jedis 的依赖,代码如下:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
然后创建一个测试方法。
public class JedisPing {
public static void main(String[] args) {
// 1.构建和 Redis 的连接
Jedis jedis = new Jedis("192.168.253.130", 6379);
// 2.密码认证
jedis.auth("javaboy");
// 3.调用 ping() 方法进行测试
String ping = jedis.ping();
// 4.输出 pong 代表 Redis 连接成功了
System.out.println(ping);
}
}
对于 Jedis 而言,一单连接上 Redis 服务端,剩下的操作就很容易了。
在 Jedis 中,由于方法的 API 和 Redis 的命令高度一致,所以 Jedis 的方法见名知意,直接使用即可。
2.2 连接池
在实际应用中,Jedis 实例我们一般都是通过连接池来获取,由于 Jedis 对象不是线程安全的,所以,当我们在使用 Jedis 对象时,从连接池获取 Jedis,使用完成之后,再还给连接池。
public class JedisPoolTest {
public static void main(String[] args) {
// 1.构建一个 Jedis 连接池
JedisPool jedisPool = new JedisPool("192.168.253.130",6379);
// 2.从连接池中获取一个 Jedis 连接
Jedis jedis = jedisPool.getResource();
// 3.密码认证
jedis.auth("javaboy");
// 4.Jedis 操作
System.out.println(jedis.ping());
// 5归还连接
jedis.close();
}
}
假如现在第4步操作抛出异常,会导致第5步无法正常执行,所以我们要对代码进行改进,第一时间想到的就是添加 finally 块。
public class JedisPoolTest {
public static void main(String[] args) {
// 1.构建一个 Jedis 连接池
JedisPool jedisPool = new JedisPool("192.168.253.130",6379);
// 2.从连接池中获取一个 Jedis 连接
Jedis jedis = jedisPool.getResource();
// 3.密码认证
jedis.auth("javaboy");
// 4.Jedis 操作
try {
System.out.println(jedis.ping());
} catch (Exception e) {
e.printStackTrace();
} finally {
// 5.归还连接
jedis.close();
}
}
}
但是这段代码无法实现强约束,我们可以做进一步的改进:
public interface CallWithJedis {
void call(Jedis jedis);
}
public class Redis {
private JedisPool jedisPool;
public Redis() {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
// 连接池最大空闲数
poolConfig.setMaxIdle(30);
// 连接池最大连接数
poolConfig.setMaxTotal(1000);
// 连接池最大等待时间,如果是 -1 表示没有限制
poolConfig.setMaxWaitMillis(30000);
// 在空闲时检查有效性
poolConfig.setTestOnBorrow(true);
/**
* 1. 连接池
* 2. Redis 地址
* 3. Redis 端口号
* 4. 连接超时时长
* 5. Redis 连接密码
*/
jedisPool = new JedisPool(poolConfig, "192.168.253.130", 6379, 30000, "javaboy");
}
public void execute(CallWithJedis callWithJedis) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
callWithJedis.call(jedis);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != jedis) {
jedis.close();
}
}
}
}
Redis redis = new Redis();
redis.execute(new CallWithJedis() {
public void call(Jedis jedis) {
System.out.println(jedis.ping());
}
});
3. Lettuce
GitHub:https://github.com/lettuce-io/lettuce-core
Lettuce 和 Jedis 的比较:
- Jedis 在实现的过程中是直接连接 Redis 的,在多个线程之间共享一个 Jedis 实例,这是线程不安全的,如果想要在多线程场景下使用 Jedis,就得使用连接池,这样每个线程都有自己的 Jedis 实例。
- Lettuce 基于目前很火的 Netty NIO 框架来创建,所以克服了 Jedis 中线程不安全的问题,Lettuce 支持同步、异步以及响应式调用,多个线程可以共享一个连接实例。
使用 Lettuce ,首先创建一个普通的 Maven 项目,添加 Lettuce 依赖:
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
简单测试案例:
public class JedisPing {
public static void main(String[] args) {
RedisClient redisClient = RedisClient.create("redis://[email protected]");
StatefulRedisConnection<String, String> connect = redisClient.connect();
RedisCommands<String, String> sync = connect.sync();
sync.set("name","zs");
System.out.println(sync.get("name"));
}
}
注意这里的密码传递方式,密码直接写在连接地址中。