package com.vci.server.cache.redis;
|
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
|
import org.apache.commons.lang3.math.NumberUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.JedisPool;
|
import redis.clients.jedis.JedisPoolConfig;
|
|
/**
|
* 对redis pool 进行hash分片
|
*
|
* @author zhengzhiyuan
|
* @since May 20, 2016
|
*/
|
public class RedisUtil {
|
private static final Logger LOGGER = LoggerFactory.getLogger(RedisUtil.class);
|
|
private static final String DEFAULT_REDIS_SEPARATOR = ";";
|
|
private static final String HOST_PORT_SEPARATOR = ":";
|
|
private JedisPool[] jedisPools = new JedisPool[0];
|
|
private static final RedisUtil INSTANCE = new RedisUtil();
|
|
private RedisUtil() {
|
initPool();
|
}
|
|
private void initPool() {
|
|
// 操作超时时间,默认2秒
|
int timeout = NumberUtils.toInt(RedisConfig.getConfigProperty("redis.timeout"), 2000);
|
// jedis池最大连接数总数,默认8
|
int maxTotal = NumberUtils.toInt(RedisConfig.getConfigProperty("redis.jedisPoolConfig.maxTotal"), 8);
|
// jedis池最大空闲连接数,默认8
|
int maxIdle = NumberUtils.toInt(RedisConfig.getConfigProperty("redis.jedisPoolConfig.maxIdle"), 8);
|
// jedis池最少空闲连接数
|
int minIdle = NumberUtils.toInt(RedisConfig.getConfigProperty("redis.jedisPoolConfig.minIdle"), 0);
|
// jedis池没有对象返回时,最大等待时间单位为毫秒
|
long maxWaitMillis = NumberUtils.toLong(RedisConfig.getConfigProperty("redis.jedisPoolConfig.maxWaitTime"), -1);
|
// 在borrow一个jedis实例时,是否提前进行validate操作
|
boolean testOnBorrow = Boolean.parseBoolean(RedisConfig.getConfigProperty("redis.jedisPoolConfig.testOnBorrow"));
|
|
// 设置jedis连接池配置
|
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
poolConfig.setMaxTotal(maxTotal);
|
poolConfig.setMaxIdle(maxIdle);
|
poolConfig.setMinIdle(minIdle);
|
poolConfig.setMaxWaitMillis(maxWaitMillis);
|
poolConfig.setTestOnBorrow(testOnBorrow);
|
|
// 取得redis的url
|
String redisUrls = RedisConfig.getConfigProperty("redis.jedisPoolConfig.urls");
|
if (redisUrls == null || redisUrls.trim().isEmpty()) {
|
throw new IllegalStateException("the urls of redis is not configured");
|
}
|
LOGGER.info("the urls of redis is {}", redisUrls);
|
|
// 生成连接池
|
List<JedisPool> jedisPoolList = new ArrayList<JedisPool>();
|
for (String redisUrl : redisUrls.split(DEFAULT_REDIS_SEPARATOR)) {
|
String[] redisUrlInfo = redisUrl.split(HOST_PORT_SEPARATOR);
|
jedisPoolList.add(new JedisPool(poolConfig, redisUrlInfo[0], Integer.parseInt(redisUrlInfo[1]), timeout));
|
}
|
|
jedisPools = jedisPoolList.toArray(jedisPools);
|
}
|
|
public static RedisUtil getInstance() {
|
return INSTANCE;
|
}
|
|
/**
|
* 实现jedis连接的获取和释放,具体的redis业务逻辑由executor实现
|
*
|
* @param executor RedisExecutor接口的实现类
|
* @return
|
*/
|
public <T> T execute(String key, RedisExecutor<T> executor) {
|
Jedis jedis = jedisPools[(0x7FFFFFFF & key.hashCode()) % jedisPools.length].getResource();
|
T result = null;
|
try {
|
result = executor.execute(jedis);
|
} finally {
|
if (jedis != null) {
|
jedis.close();
|
}
|
}
|
return result;
|
}
|
|
public String set(final String key, final String value) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.set(key, value);
|
}
|
});
|
}
|
|
public String set(final String key, final String value, final String nxxx, final String expx, final long time) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.set(key, value, nxxx, expx, time);
|
}
|
});
|
}
|
|
public String get(final String key) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.get(key);
|
}
|
});
|
}
|
|
public Boolean exists(final String key) {
|
return execute(key, new RedisExecutor<Boolean>() {
|
@Override
|
public Boolean execute(Jedis jedis) {
|
return jedis.exists(key);
|
}
|
});
|
}
|
|
public Long setnx(final String key, final String value) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.setnx(key, value);
|
}
|
});
|
}
|
|
public String setex(final String key, final int seconds, final String value) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.setex(key, seconds, value);
|
}
|
});
|
}
|
|
public Long expire(final String key, final int seconds) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.expire(key, seconds);
|
}
|
});
|
}
|
|
public Long incr(final String key) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.incr(key);
|
}
|
});
|
}
|
|
public Long decr(final String key) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.decr(key);
|
}
|
});
|
}
|
|
public Long hset(final String key, final String field, final String value) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.hset(key, field, value);
|
}
|
});
|
}
|
|
public String hget(final String key, final String field) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.hget(key, field);
|
}
|
});
|
}
|
|
public Long hdel(final String key, final String field) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.hdel(key, field);
|
}
|
});
|
}
|
|
public String hmset(final String key, final Map<String, String> hash) {
|
return execute(key, new RedisExecutor<String>() {
|
@Override
|
public String execute(Jedis jedis) {
|
return jedis.hmset(key, hash);
|
}
|
});
|
}
|
|
public List<String> hmget(final String key, final String... fields) {
|
return execute(key, new RedisExecutor<List<String>>() {
|
@Override
|
public List<String> execute(Jedis jedis) {
|
return jedis.hmget(key, fields);
|
}
|
});
|
}
|
|
public Long del(final String key) {
|
return execute(key, new RedisExecutor<Long>() {
|
@Override
|
public Long execute(Jedis jedis) {
|
return jedis.del(key);
|
}
|
});
|
}
|
|
public Map<String, String> hgetAll(final String key) {
|
return execute(key, new RedisExecutor<Map<String, String>>() {
|
@Override
|
public Map<String, String> execute(Jedis jedis) {
|
return jedis.hgetAll(key);
|
}
|
});
|
}
|
|
public void destroy() {
|
for (int i = 0; i < jedisPools.length; i++) {
|
jedisPools[i].close();
|
}
|
}
|
}
|