jedispool 连 redis 高并发卡死

1 篇文章 0 订阅

java端在使用jedispool 连接redis的时候,在高并发的时候经常卡死,或报连接异常,JedisConnectionException,或者getResource 异常等各种问题

在使用jedispool 的时候一定要注意两点

1。 在获取 jedisPool和jedis的时候加上线程同步,保证不要创建过多的jedispool 和 jedis

2。 用完Jedis实例后需要返还给JedisPool

整理了一下redis工具类,通过大量测试和高并发测试的

import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis 工具类
* @author caspar
* https://blog.csdn.net/tuposky
*/
public class RedisUtil {
protected static Logger logger = Logger. getLogger( RedisUtil. class);
//Redis服务器IP
private static String ADDR_ARRAY = FileUtil. getPropertyValue( "/properties/redis.properties", "server");
//Redis的端口号
private static int PORT = FileUtil. getPropertyValueInt( "/properties/redis.properties", "port");
//访问密码
// private static String AUTH = FileUtil.getPropertyValue("/properties/redis.properties", "auth");
//可用连接实例的最大数目,默认值为8;
//如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。
private static int MAX_ACTIVE = FileUtil. getPropertyValueInt( "/properties/redis.properties", "max_active");;
//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = FileUtil. getPropertyValueInt( "/properties/redis.properties", "max_idle");;
//等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;
private static int MAX_WAIT = FileUtil. getPropertyValueInt( "/properties/redis.properties", "max_wait");;
//超时时间
private static int TIMEOUT = FileUtil. getPropertyValueInt( "/properties/redis.properties", "timeout");;
//在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的;
private static boolean TEST_ON_BORROW = FileUtil. getPropertyValueBoolean( "/properties/redis.properties", "test_on_borrow");;
private static JedisPool jedisPool = null;
/**
* redis过期时间,以秒为单位
*/
public final static int EXRP_HOUR = 60* 60; //一小时
public final static int EXRP_DAY = 60* 60* 24; //一天
public final static int EXRP_MONTH = 60* 60* 24* 30; //一个月
/**
* 初始化Redis连接池
*/
private static void initialPool(){
try {
JedisPoolConfig config = new JedisPoolConfig();
config. setMaxTotal( MAX_ACTIVE);
config. setMaxIdle( MAX_IDLE);
config. setMaxWaitMillis( MAX_WAIT);
config. setTestOnBorrow( TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR_ARRAY. split( ",")[ 0], PORT, TIMEOUT);
} catch ( Exception e) {
logger. error( "First create JedisPool error : "+e);
try{
//如果第一个IP异常,则访问第二个IP
JedisPoolConfig config = new JedisPoolConfig();
config. setMaxTotal( MAX_ACTIVE);
config. setMaxIdle( MAX_IDLE);
config. setMaxWaitMillis( MAX_WAIT);
config. setTestOnBorrow( TEST_ON_BORROW);
jedisPool = new JedisPool(config, ADDR_ARRAY. split( ",")[ 1], PORT, TIMEOUT);
} catch( Exception e2){
logger. error( "Second create JedisPool error : "+e2);
}
}
}
/**
* 在多线程环境同步初始化
*/
private static synchronized void poolInit() {
if (jedisPool == null) {
initialPool();
}
}
/**
* 同步获取Jedis实例
* @return Jedis
*/
public synchronized static Jedis getJedis() {
if (jedisPool == null) {
poolInit();
}
Jedis jedis = null;
try {
if (jedisPool != null) {
jedis = jedisPool. getResource();
}
} catch ( Exception e) {
logger. error( "Get jedis error : "+e);
} finally{
returnResource(jedis);
}
return jedis;
}
/**
* 释放jedis资源
* @param jedis
*/
public static void returnResource( final Jedis jedis) {
if (jedis != null && jedisPool != null) {
jedisPool. returnResource(jedis);
}
}
/**
* 设置 String
* @param key
* @param value
*/
public static void setString( String key , String value){
try {
value = StringUtil. isEmpty(value) ? "" : value;
getJedis(). set(key,value);
} catch ( Exception e) {
logger. error( "Set key error : "+e);
}
}
/**
* 设置 过期时间
* @param key
* @param seconds 以秒为单位
* @param value
*/
public static void setString( String key , int seconds, String value){
try {
value = StringUtil. isEmpty(value) ? "" : value;
getJedis(). setex(key, seconds, value);
} catch ( Exception e) {
logger. error( "Set keyex error : "+e);
}
}
/**
* 获取String值
* @param key
* @return value
*/
public static String getString( String key){
if( getJedis() == null || ! getJedis(). exists(key)){
return null;
}
return getJedis(). get(key);
}
}

其中 jedis官方现在最高版本为2.9.0 而jedis.close()取代pool.returnResource(Jedis)方法将3.0版本开始,所以暂时只能使用后者。

//官方重写了close。
try {
jedis = pool. getResource();
} finally {
if (jedis != null) {
jedis. close();
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值