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=***
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;
}
}