Jedis连接池配置详解
写代码是日益精进的不是一蹴而就的,以前写代码就是各处借鉴,然后完成项目的需要就放在那里了,时间长了接触的多了,再来看之前代码总觉得哪里不太对劲(简直垃圾,这能是我写的?),觉得需要改变,这次顺便记录下来,也分享给大家,相当于优化轨迹、版本控制等等,以后还有可能改变,但是最终有迹可循~ 不会麻爪~
application.yml
redis:
host: 127.0.0.1
port: 6379
password: yourpassword
database: 1
# 是否分布式
isSharded: false
# 最大连接数
maxTotal: 5000
# 最大空闲连接数
maxIdle: 1000
# 建立连接时,最大等待时间
maxWaitMillis: 60000
# 建立连接时,是否进行有效性检查
testOnBorrow: true
JedisPool.java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import redis.clients.jedis.*;
import redis.clients.jedis.exceptions.JedisConnectionException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @Author: Wenx
* @Description: Redis连接池
* @Date: Created in 2019/12/15 16:35
* @Modified By:
*/
@Configuration
public class JedisPool {
private static Logger logger = LoggerFactory.getLogger(JedisPool.class);
@Autowired
private Environment env;
private String[] hosts;
private String[] ports;
private String[] passwords;
private String[] databases;
private boolean isSharded;
private int maxTotal;
private int maxIdle;
private long maxWaitMillis;
private boolean testOnBorrow;
/**
* 单节点连接池
*/
private static redis.clients.jedis.JedisPool jedisPool;
/**
* 分布式连接池
*/
private static ShardedJedisPool shardedJedisPool;
@Bean
public void loadConfig() {
String host = env.getProperty("redis.host");
if (null != host) {
hosts = host.split(",");
}
String port = env.getProperty("redis.port");
if (null != port) {
ports = port.split(",");
}
String password = env.getProperty("redis.password");
if (null != password) {
passwords = password.split(",");
}
String database = env.getProperty("redis.database");
if (null != database) {
databases = database.split(",");
}
isSharded = env.getProperty("redis.isSharded", Boolean.class);
maxTotal = env.getProperty("redis.maxTotal", Integer.class);
maxIdle = env.getProperty("redis.maxIdle", Integer.class);
maxWaitMillis = env.getProperty("redis.maxWaitMillis", Long.class);
testOnBorrow = env.getProperty("redis.testOnBorrow", Boolean.class);
}
@Bean
public JedisPoolConfig jedisPoolConfig() {
// 池基本配置
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMaxWaitMillis(maxWaitMillis);
config.setTestOnBorrow(testOnBorrow);
return config;
}
@Bean
public String initial(@Qualifier("jedisPoolConfig") JedisPoolConfig config) {
if (null != hosts && hosts.length > 0) {
if (isSharded) {
initShardedPool(config);
} else {
initPool(config);
}
} else {
logger.warn("jedis pool initial host invalid.");
}
return null;
}
/**
* 初始化单节点池
*
* @param config JedisPoolConfig
*/
private void initPool(JedisPoolConfig config) {
logger.info("one redis are:------------------------------{");
logger.debug("host:[{}], port:[{}].", hosts[0], ports[0]);
jedisPool = new redis.clients.jedis.JedisPool(config,
hosts[0], Integer.parseInt(ports[0]), 2000,
null == passwords ? null : passwords[0],
null == databases ? 0 : Integer.parseInt(databases[0]));
logger.info("}------------------------------");
}
/**
* 初始化分布式池
*
* @param config JedisPoolConfig
*/
private void initShardedPool(JedisPoolConfig config) {
logger.info("shard redis are:------------------------------{");
// slave连接
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
for (int i = 0; i < hosts.length; i++) {
logger.debug("host:[{}], port:[{}].", hosts[i], ports[i]);
JedisShardInfo jedisShardInfo = new JedisShardInfo(
hosts[i], Integer.parseInt(ports[i]), "master");
jedisShardInfo.setPassword(null == passwords ? null : passwords[0]);
shards.add(jedisShardInfo);
}
shardedJedisPool = new ShardedJedisPool(config, shards);
logger.info("}------------------------------");
}
/**
* 获取连接
*
* @return Jedis
*/
public static Jedis getJedis() {
int count = 20;
while ((count--) > 0) {
try {
return jedisPool.getResource();
} catch (JedisConnectionException e) {
logger.warn("jedis connection failed, try reconnecting.");
try {
TimeUnit.SECONDS.sleep(2L);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
} catch (Exception e) {
logger.error("jedis pool get failed, jedisInfo ... NumActive=[{}], NumIdle=[{}], NumWaiters=[{}], isClosed=[{}], error:[{}].",
jedisPool.getNumActive(), jedisPool.getNumIdle(),
jedisPool.getNumWaiters(), jedisPool.isClosed(), e);
break;
}
}
return null;
}
/**
* 获取连接
*
* @return ShardedJedis
*/
public static ShardedJedis getShardedJedis() {
if (shardedJedisPool != null) {
return shardedJedisPool.getResource();
}
return null;
}
/**
* 关闭连接
*
* @param jedis Jedis
*/
public static void close(Jedis jedis) {
try {
if (jedis != null) {
jedis.close();
}
} catch (Exception e) {
logger.error("return jedis resource exception", e);
}
}
/**
* 关闭连接
*
* @param shardedJedis ShardedJedis
*/
public static void close(ShardedJedis shardedJedis) {
try {
if (shardedJedis != null) {
shardedJedis.close();
}
} catch (Exception e) {
logger.error("return sharded jedis resource exception", e);
}
}
/**
* 销毁单节点池
*/
public static void destroy() {
try {
jedisPool.destroy();
} catch (Exception e) {
logger.error("jedis pool destroy exception", e);
}
}
/**
* 销毁分布式池
*/
public static void destroySharded() {
try {
shardedJedisPool.destroy();
} catch (Exception e) {
logger.error("sharded jedis pool destroy exception", e);
}
}
}