java端在使⽤jedispool 连接redis的时候,在⾼并发的时候经常死锁,或报连接异常,JedisConnectionException,或者getResource 异常等各种问题
在使⽤jedispool 的时候⼀定要注意两点
1。 在获取 jedisPool和jedis的时候加上线程同步,保证不要创建过多的jedispool 和 jedis2。 ⽤完Jedis实例后需要返还给JedisPool
整理了⼀下redis⼯具类,通过⼤量测试和⾼并发测试的
package com.caspar.util;
import java.util.concurrent.locks.ReentrantLock; import org.apache.log4j.Logger; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig; /**
* Redis ⼯具类 * @author caspar * */
public class RedisUtil {
protected static ReentrantLock lockPool = new ReentrantLock(); protected static ReentrantLock lockJedis = new ReentrantLock();
protected static Logger logger = Logger.getLogger(RedisUtil.class);
//Redis服务器IP
private static String ADDR_ARRAY = FileUtil.getPropertyValue(\"/properties/redis.properties\
//Redis的端⼝号
private static int PORT = FileUtil.getPropertyValueInt(\"/properties/redis.properties\
//访问密码
// private static String AUTH = FileUtil.getPropertyValue(\"/properties/redis.properties\
//可⽤连接实例的最⼤数⽬,默认值为8;
//如果赋值为-1,则表⽰不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)。 private static int MAX_ACTIVE = FileUtil.getPropertyValueInt(\"/properties/redis.properties\
//控制⼀个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。
private static int MAX_IDLE = FileUtil.getPropertyValueInt(\"/properties/redis.properties\
//等待可⽤连接的最⼤时间,单位毫秒,默认值为-1,表⽰永不超时。如果超过等待时间,则直接抛出JedisConnectionException; private static int MAX_WAIT = FileUtil.getPropertyValueInt(\"/properties/redis.properties\
//超时时间
private static int TIMEOUT = FileUtil.getPropertyValueInt(\"/properties/redis.properties\
//在borrow⼀个jedis实例时,是否提前进⾏validate操作;如果为true,则得到的jedis实例均是可⽤的;
private static boolean TEST_ON_BORROW = FileUtil.getPropertyValueBoolean(\"/properties/redis.properties\
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(\ } 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(\ }catch(Exception e2){
logger.error(\"Second create JedisPool error : \"+e2); } } } /**
* 在多线程环境同步初始化 */
private static void poolInit() {
//断⾔ ,当前锁是否已经锁住,如果锁住了,就啥也不⼲,没锁的话就执⾏下⾯步骤 assert ! lockPool.isHeldByCurrentThread(); lockPool.lock(); try {
if (jedisPool == null) { initialPool(); }
}catch(Exception e){ e.printStackTrace(); } finally {
lockPool.unlock(); } }
public static Jedis getJedis() {
//断⾔ ,当前锁是否已经锁住,如果锁住了,就啥也不⼲,没锁的话就执⾏下⾯步骤 assert ! lockJedis.isHeldByCurrentThread(); lockJedis.lock();
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); lockJedis.unlock(); }
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 synchronized 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 synchronized 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 synchronized static String getString(String key){ if(getJedis() == null || !getJedis().exists(key)){ return null; }
return getJedis().get(key); } }
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
因篇幅问题不能全部显示,请点此查看更多更全内容