频繁的创建和销毁
Jedis
对象会占⽤资源,为提⾼性能,减少
Socket
的创建和销毁对性能的影响,
Jedis
提供了连接
池
JedisPool
。
JedisPool
是⼀个线程安全的⽹络连接池。可以⽤
JedisPool
创建⼀些可靠
Jedis
实例,可以从池中获取
Jedis
实例,使
⽤完后再把
Jedis
实例归还给
JedisPool
连接池。合理的
JedisPool
资源池参数设置能够有效地提升
Redis
性能。
一·JedisPool
使⽤
<!-- 在项⽬的pom.xml 配置⽂件中添加 JedisPool连接池依赖 --><dependency><groupId> org.apache.commons </groupId><artifactId> commons-pool2 </artifactId><version> 2.11.1 </version></dependency><!-- //.在项⽬的pom.xml⽂件中导⼊Java和Redis打交道的API客户端依赖--><dependency><groupId> redis.clients </groupId><artifactId> jedis </artifactId><version> 3.9.0 </version></dependency>
2.在
resources
⽬录下创建
redis.properties
⽂件并在该⽂件中声明
Redis
服务器连接配置参数。
# Redis 服务器地址 域名或 IP)redis.host = 192.168.48.76# Redis 服务器连接端⼝ (Redis 默认端⼝号是 6379)redis.port = 6379# Redis 服务器连接密码 ( 默认为空 )redis.password =# 最⼤连接数redis.maxTotal = 1000# 最⼤空闲连接数redis.maxIdle = 30# 最⼤的阻塞时⻓redis.maxWait = 60000# 向资源池借⽤连接时是否做连接有效性检测( ping )。检测到的⽆效连接将会被移除redis.testOnBorrow = true
3.
在
com.yx
包下定义
JedisPoolUtil
类,使⽤单例模式优化
Jedis
连接池
package com.example.demo5;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.time.Duration;
import java.util.Properties;
/** 单例模式优化Jedis连接池 */
public class JedisPoolUtil {
// Redis服务器地址(域名或IP)
private static String host;
// Redis服务器连接端⼝(Redis默认端⼝号是6379)
private static String port;
// Redis服务器连接密码(默认为空)
private static String password;
// 最⼤连接数
private static String maxTotal;
// 最⼤空闲连接数
private static String maxIdle;
// 最⼤的阻塞时⻓
private static String maxWait;
// 向资源池借⽤连接时是否做连接有效性检测(ping)。检测到的⽆效连接将会被移除
private static String testOnBorrow;
private volatile static JedisPool jedisPool = null;
private volatile static Jedis jedis = null;
static {
// 读取配置⽂件。加载redis.properties配置⽂件,通过反射的⽅式得到⽂件输⼊流
InputStream inputStream =
JedisPoolUtil.class.getClassLoader().getResourceAsStream("redis.properties");
// 创建读取配置⽂件的properties对象,Properties继承了Hashtable类,Hashtable类实现了Map接⼝
Properties properties = new Properties();
try {
/*
* 1.⽅法作⽤:从字节输⼊流中读取键值对。该⽅法常⽤于读取配置⽂件。
* 2.参数含义:参数中使⽤了字节输⼊流,通过流对象可以关联到某⽂件上,这样就能够加载⽂本中
的数据了。⽂本中的数据,
* 必须是键值对形式,可以使⽤空格、等号、冒号等符号分隔。
*/
properties.load(inputStream);
// 获取Redis数据库连接信息
host = properties.getProperty("redis.host");
port = properties.getProperty("redis.port");
password = properties.getProperty("redis.password");
maxTotal = properties.getProperty("redis.maxTotal");
maxIdle = properties.getProperty("redis.maxIdle");
maxWait = properties.getProperty("redis.maxWait");
testOnBorrow= properties.getProperty("redis.testOnBorrow");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private JedisPoolUtil() {
}
private static JedisPool getInstance() {
// 单例模式实现:双检锁/双重校验锁。这种⽅式采⽤双锁机制,安全且在多线程情况下能保持⾼性能
if(jedisPool == null) {
synchronized (JedisPoolUtil.class) {
if(jedisPool == null) {
// 创建⼀个配置对象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(maxTotal)); // 资源池中的最⼤连接数
config.setMaxIdle(Integer.parseInt(maxIdle)); // 资源池允许的最⼤空闲连接数
// 当资源池连接⽤尽后,调⽤者的最⼤等待时间(单位为毫秒)
config.setMaxWait(Duration.ofMillis(Integer.parseInt(maxWait)));
// 向资源池借⽤连接时是否做连接有效性检测(业务量很⼤时候建议设置为false,减少⼀次ping的开销)
config.setTestOnBorrow(Boolean.valueOf(testOnBorrow));
// 初始化JedisPool
jedisPool = new JedisPool(config, host, Integer.parseInt(port));
}
}
}
return jedisPool;
}
/** 获取连接⽅法 */
public static Jedis getJedis() {
if (jedis == null) {
// 获取连接
jedis = getInstance().getResource();
}
return jedis;
}
}
4.下创建
JedisPoolTests
类,测试
Jedis
连接池
package com.example.demo5;
import redis.clients.jedis.Jedis;
/** 测试Jedis连接池 */
public class JedisPoolTests {
public static void main(String[] args) {
Jedis jedis1 = JedisPoolUtil.getJedis();
Jedis jedis2 = JedisPoolUtil.getJedis();
System.out.println(jedis1==jedis2);
jedis1.set("username", "yuanxin");
System.out.println("Redis存储的字符串为: "+ jedis1.get("username"));
}
}