Jedis连接池配置

jopen 10年前

摘要: 项目使用spring3.1版本,需要分环境(RND/Relesas/...)在Spring中配置Jedis连接池。此配置未使用Redis的分片。

1.使用MAVEN引入使用的包。

<dependency>      <groupId>redis.clients</groupId>      <artifactId>jedis</artifactId>      <version>2.1.0</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-core</artifactId>      <version>3.1.0.RELEASE</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context</artifactId>      <version>3.1.0.RELEASE</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-context-support</artifactId>      <version>3.1.0.RELEASE</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-beans</artifactId>      <version>3.1.0.RELEASE</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>org.springframework.context</artifactId>      <version>3.1.0.RELEASE</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-test</artifactId>      <version>3.1.0.RELEASE</version>      <scope>test</scope>  </dependency>  <dependency>      <groupId>commons-io</groupId>      <artifactId>commons-io</artifactId>      <version>1.3.2</version>  </dependency>  <dependency>      <groupId>commons-lang</groupId>      <artifactId>commons-lang</artifactId>      <version>2.3</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.10</version>      <scope>test</scope>  </dependency>  <dependency>      <groupId>org.aspectj</groupId>      <artifactId>aspectjweaver</artifactId>      <version>1.6.12</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>net.sourceforge.cglib</groupId>      <artifactId>com.springsource.net.sf.cglib</artifactId>      <version>2.2.0</version>      <scope>provided</scope>  </dependency>  <dependency>      <groupId>log4j</groupId>      <artifactId>log4j</artifactId>      <version>1.2.8</version>  </dependency>

2.Jedis的连接池配置需要用到org.apache.commons.pool.impl.GenericObjectPool.Config.class,此类是 GenericObjectPool的一个内部类,使用spring xml配置时需要转换成以下自定义类。

package com.antilost.redis.util;    import org.apache.commons.pool.impl.GenericObjectPool;    /**   * User: ***   * Date: 13-8-27   * Time: 下午3:49   */  public class GenericObjectPoolConfigWrapper {        private final GenericObjectPool.Config config;        public GenericObjectPoolConfigWrapper() {          this.config = new GenericObjectPool.Config();      }        public GenericObjectPool.Config getConfig() {          return config;      }        public int getMaxIdle() {          return this.config.maxIdle;      }        public void setMaxIdle(int maxIdle) {          this.config.maxIdle = maxIdle;      }        public int getMinIdle() {          return this.config.minIdle;      }        public void setMinIdle(int minIdle) {          this.config.minIdle = minIdle;      }        public int getMaxActive() {          return this.config.maxActive;      }        public void setMaxActive(int maxActive) {          this.config.maxActive = maxActive;      }        public long getMaxWait() {          return this.config.maxWait;      }        public void setMaxWait(long maxWait) {          this.config.maxWait = maxWait;      }        public byte getWhenExhaustedAction() {          return this.config.whenExhaustedAction;      }        public void setWhenExhaustedAction(byte whenExhaustedAction) {          this.config.whenExhaustedAction = whenExhaustedAction;      }        public boolean isTestOnBorrow() {          return this.config.testOnBorrow;      }        public void setTestOnBorrow(boolean testOnBorrow) {          this.config.testOnBorrow = testOnBorrow;      }        public boolean isTestOnReturn() {          return this.config.testOnReturn;      }        public void setTestOnReturn(boolean testOnReturn) {          this.config.testOnReturn = testOnReturn;      }        public boolean isTestWhileIdle() {          return this.config.testWhileIdle;      }        public void setTestWhileIdle(boolean testWhileIdle) {          this.config.testWhileIdle = testWhileIdle;      }        public long getTimeBetweenEvictionRunsMillis() {          return this.config.timeBetweenEvictionRunsMillis;      }        public void setTimeBetweenEvictionRunsMillis( long timeBetweenEvictionRunsMillis) {          this.config.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;      }        public int getNumTestsPerEvictionRun() {          return this.config.numTestsPerEvictionRun;      }        public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {          this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;      }        public long getMinEvictableIdleTimeMillis() {          return this.config.minEvictableIdleTimeMillis;      }        public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {          this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;      }        public long getSoftMinEvictableIdleTimeMillis() {          return this.config.softMinEvictableIdleTimeMillis;      }        public void setSoftMinEvictableIdleTimeMillis( long softMinEvictableIdleTimeMillis) {          this.config.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis;      }        public boolean isLifo() {          return this.config.lifo;      }        public void setLifo(boolean lifo) {          this.config.lifo = lifo;      }  }

3.在Spring配置文件中注入GenericObjectPoolConfigWrapper.java类

<aop:aspectj-autoproxy/>  <context:annotation-config />  <context:property-placeholder location="classpath:jedis.properties" ignore-unresolvable="true"/>  <bean id="jedisPoolConfig" class="com.antilost.redis.util.GenericObjectPoolConfigWrapper">          <!--最大连接数-->   <property name="maxActive" value="${${redis.pool.maxActive}}" />          <!--最大空闲连接数-->   <property name="maxIdle" value="${${redis.pool.maxIdle}}" />          <!--初始化连接数-->   <property name="minIdle" value="${${redis.pool.minIdle}}"/>          <!--最大等待时间-->   <property name="maxWait" value="${${redis.pool.maxWait}}" />          <!--对拿到的connection进行validateObject校验-->   <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" />          <!--在进行returnObject对返回的connection进行validateObject校验-->   <property name="testOnReturn" value="${redis.pool.testOnReturn}" />          <!--定时对线程池中空闲的链接进行validateObject校验-->          <property name="testWhileIdle" value="true" />  </bean>

4.Redis的连接配置文件jedis.properties中,定义了各个环境的连接参数,具体配置如下

redis.pool.maxActive=redis.pool.maxActive.${ServerType}  redis.pool.maxIdle=redis.pool.maxIdle.${ServerType}  redis.pool.maxWait=redis.pool.maxWait.${ServerType}  redis.pool.minIdle=redis.pool.minIdle.${ServerType}  redis.host=redis.host.${ServerType}  redis.port=redis.port.${ServerType}  redis.password=redis.password.${ServerType}  redis.pool.testOnBorrow=true  redis.pool.testOnReturn=true  redis.timeout=1000  #C  #REL  redis.pool.maxActive.REL=200  redis.pool.maxIdle.REL=50  redis.pool.minIdle.REL=10  redis.pool.maxWait.REL=300  redis.host.REL=192.168.*.*  redis.port.REL=6379  redis.password.REL=***    #VRF  redis.pool.maxActive.VRF=200  redis.pool.maxIdle.VRF=50  redis.pool.minIdle.VRF=10  redis.pool.maxWait.VRF=300  redis.host.VRF=192.168.*.*  redis.port.VRF=6379  redis.password.VRF=***
根据系统环境变量JVM中ServerType的值,取不同的配置,实现多环境(测试环境、生产环境)集成。


5.Redis连接池配置

<bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">    <constructor-arg index="0">              <bean factory-bean="jedisPoolConfig" factory-method="getConfig"/>    </constructor-arg>          <constructor-arg index="1" value="${${redis.host}}"/>          <constructor-arg index="2" value="${${redis.port}}"/>          <!--timeout-->          <constructor-arg index="3" value="${redis.timeout}"/>          <constructor-arg index="4" value="${${redis.password}}"/>  </bean>
6.Redis 工具类
public abstract class JCacheTools {      public abstract int getDBIndex();      /**       * 默认日志打印logger_default       */      public static Logger logger_default = Logger.getLogger("logger_jCache_default");      /**       * 失败日志logger,用于定期del指定的key       */      public static Logger logger_failure = Logger.getLogger("logger_jCache_failure");        @Resource      protected JedisPool jedisPool;        protected Jedis getJedis() throws JedisException {          Jedis jedis = null;          try {              jedis = jedisPool.getResource();          } catch (JedisException e) {              LogContext.instance().warn(logger_failure, "failed:jedisPool getResource.", e);              if(jedis!=null){                  jedisPool.returnBrokenResource(jedis);              }              throw e;          }          return jedis;      }        protected void release(Jedis jedis, boolean isBroken) {          if (jedis != null) {              if (isBroken) {                  jedisPool.returnBrokenResource(jedis);              } else {                  jedisPool.returnResource(jedis);              }          }      }        protected String addStringToJedis(String key, String value, int cacheSeconds, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          String lastVal = null;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              lastVal = jedis.getSet(key, value);              if(cacheSeconds!=0){                  jedis.expire(key,cacheSeconds);              }              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, value);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, value, e);          } finally {              release(jedis, isBroken);          }          return lastVal;      }        protected void addStringToJedis(Map<String,String> batchData, int cacheSeconds, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              Pipeline pipeline = jedis.pipelined();              for(Map.Entry<String,String> element:batchData.entrySet()){                  if(cacheSeconds!=0){                      pipeline.setex(element.getKey(),cacheSeconds,element.getValue());                  }else{                      pipeline.set(element.getKey(),element.getValue());                  }              }              pipeline.sync();              LogContext.instance().debug(logger_default, "succeed:" + methodName,batchData.size());          } catch (Exception e) {              isBroken = true;              e.printStackTrace();          } finally {              release(jedis, isBroken);          }      }        protected void addListToJedis(String key, List<String> list, int cacheSeconds, String methodName) {          if (list != null && list.size() > 0) {              Jedis jedis = null;              boolean isBroken = false;              try {                  jedis = this.getJedis();                  jedis.select(getDBIndex());                  if (jedis.exists(key)) {                      jedis.del(key);                  }                  for (String aList : list) {                      jedis.rpush(key, aList);                  }                  if(cacheSeconds!=0){                      jedis.expire(key, cacheSeconds);                  }                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, list.size());              } catch (JedisException e) {                  isBroken = true;                  LogContext.instance().warn(logger_failure, "failed:" + methodName, key, list.size(), e);              } catch (Exception e) {                  isBroken = true;                  LogContext.instance().warn(logger_failure, "failed:" + methodName, key, list.size(), e);              } finally {                  release(jedis, isBroken);              }          }      }        protected void addToSetJedis(String key, String[] value, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              jedis.sadd(key,value);              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, value);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, value, e);          } finally {              release(jedis, isBroken);          }      }        protected void removeSetJedis(String key,String value, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              jedis.srem(key,value);              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, value);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, value, e);          } finally {              release(jedis, isBroken);          }      }        protected void pushDataToListJedis(String key, String data, int cacheSeconds, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              jedis.rpush(key, data);              if(cacheSeconds!=0){                  jedis.expire(key,cacheSeconds);              }              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, data);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, data, e);          } finally {              release(jedis, isBroken);          }      }      protected void pushDataToListJedis(String key,List<String> batchData, int cacheSeconds, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              jedis.del(key);              jedis.lpush(key,batchData.toArray(new String[batchData.size()]));              if(cacheSeconds!=0)                  jedis.expire(key,cacheSeconds);              LogContext.instance().debug(logger_default, "succeed:" + methodName,batchData!=null?batchData.size():0);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, batchData!=null?batchData.size():0, e);          } finally {              release(jedis, isBroken);          }      }        /**       * 删除list中的元素       * @param key       * @param values       * @param methodName       */      protected void deleteDataFromListJedis(String key,List<String> values, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              Pipeline pipeline = jedis.pipelined();              if(values!=null && !values.isEmpty()){                  for (String val:values){                      pipeline.lrem(key,0,val);                  }              }              pipeline.sync();              LogContext.instance().debug(logger_default, "succeed:" + methodName,values!=null?values.size():0);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, values!=null?values.size():0, e);          } finally {              release(jedis, isBroken);          }      }        protected void addHashMapToJedis(String key, Map<String, String> map, int cacheSeconds, boolean isModified, String methodName) {          boolean isBroken = false;          Jedis jedis = null;          if (map != null && map.size() > 0) {              try {                  jedis = this.getJedis();                  jedis.select(getDBIndex());                  jedis.hmset(key, map);                  if (cacheSeconds >= 0)                      jedis.expire(key, cacheSeconds);                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, map.size());              } catch (Exception e) {                  isBroken = true;                  LogContext.instance().warn(logger_failure, "failed:" + methodName, key, map.size(), e);              } finally {                  release(jedis, isBroken);              }          }      }        protected void addHashMapToJedis(String key, String field, String value, int cacheSeconds, String methodName) {          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              if (jedis != null) {                  jedis.select(getDBIndex());                  jedis.hset(key, field, value);                  jedis.expire(key, cacheSeconds);                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, field, value);              }          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, field, value, e);          }finally {              release(jedis, isBroken);          }      }        protected void updateHashMapToJedis(String key, String incrementField, long incrementValue, String dateField, String dateValue, String methodName) {          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              jedis.hincrBy(key, incrementField, incrementValue);              jedis.hset(key, dateField, dateValue);              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, incrementField, incrementValue);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, incrementField, incrementValue, e);          }finally {              release(jedis, isBroken);          }      }        public String getStringFromJedis(String key, String methodName) {          String value = null;          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              if (jedis.exists(key)) {                  value = jedis.get(key);                  value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value)?value:null;                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, value);              }          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, value, e);          } finally {              release(jedis, isBroken);          }          return value;      }        public List<String> getStringFromJedis(String[] keys, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              return jedis.mget(keys);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, Arrays.toString(keys), e);          } finally {              release(jedis, isBroken);          }          return null;      }        protected List<String> getListFromJedis(String key, String methodName) throws JMSCacheException {          List<String> list = null;          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              if (jedis.exists(key)) {                  list = jedis.lrange(key, 0, -1);                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, list != null ? list.size() : 0);              }          } catch (JedisException e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, list != null ? list.size() : 0, e);          } finally {              release(jedis, isBroken);          }          return list;      }        protected Set<String> getSetFromJedis(String key, String methodName) throws JMSCacheException {          Set<String> list = null;          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              if (jedis.exists(key)) {                  list = jedis.smembers(key);                  LogContext.instance().debug(logger_default, "succeed:" + methodName, key, list != null ? list.size() : 0);              }          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, list != null ? list.size() : 0, e);          } finally {              release(jedis, isBroken);          }          return list;      }        protected Map<String, String> getHashMapFromJedis(String key, String methodName) {          Map<String, String> hashMap = null;          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              hashMap = jedis.hgetAll(key);              LogContext.instance().debug(logger_default, "succeed:" + methodName, key, hashMap != null ? hashMap.size() : 0);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, hashMap != null ? hashMap.size() : 0, e);          } finally {              release(jedis, isBroken);          }          return hashMap;      }        protected String getHashMapValueFromJedis(String key, String field, String methodName) {          String value = null;          boolean isBroken = false;          Jedis jedis = null;          try {              jedis = this.getJedis();              if (jedis != null) {                  jedis.select(getDBIndex());                  if (jedis.exists(key)) {                      value = jedis.hget(key, field);                      LogContext.instance().debug(logger_default, "succeed:" + methodName, key, field, value);                  }              }          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, key, field, value, e);          } finally {              release(jedis, isBroken);          }          return value;      }        public Long getIdentifyId(String identifyName ,String methodName) {          boolean isBroken = false;          Jedis jedis = null;          Long identify=null;          try {              jedis = this.getJedis();              if (jedis != null) {                  jedis.select(getDBIndex());                  identify = jedis.incr(identifyName);                  if(identify==0){                      return jedis.incr(identifyName);                  }else {                      return identify;                  }              }          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:" + methodName, identifyName, "", identify, e);          } finally {              release(jedis, isBroken);          }          return null;      }          /**       * 删除某db的某个key值       * @param key       * @return       */      public Long delKeyFromJedis(String key) {          boolean isBroken = false;          Jedis jedis = null;          long result = 0;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              LogContext.instance().debug(logger_default, "succeed:delKeyFromJedis");              return jedis.del(key);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:delKeyFromJedis", e);          } finally {              release(jedis, isBroken);          }          return result;      }        /**       * 根据dbIndex flushDB每个shard       *       * @param dbIndex       */      public void flushDBFromJedis(int dbIndex) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(dbIndex);              jedis.flushDB();              LogContext.instance().debug(logger_default, "succeed:flushDBFromJedis");          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:flushDBFromJedis", e);          } finally {              release(jedis, isBroken);          }      }        public boolean existKey(String key, String methodName) {          Jedis jedis = null;          boolean isBroken = false;          try {              jedis = this.getJedis();              jedis.select(getDBIndex());              LogContext.instance().debug(logger_default, "succeed:"+methodName);              return jedis.exists(key);          } catch (Exception e) {              isBroken = true;              LogContext.instance().warn(logger_failure, "failed:"+methodName, e);          } finally {              release(jedis, isBroken);          }          return false;      }    }