Jedis连接池配置
jopen
11年前
摘要: 项目使用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; } }