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 jedisPoolList = new ArrayList(); 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 execute(String key, RedisExecutor 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() { @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() { @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() { @Override public String execute(Jedis jedis) { return jedis.get(key); } }); } public Boolean exists(final String key) { return execute(key, new RedisExecutor() { @Override public Boolean execute(Jedis jedis) { return jedis.exists(key); } }); } public Long setnx(final String key, final String value) { return execute(key, new RedisExecutor() { @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() { @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() { @Override public Long execute(Jedis jedis) { return jedis.expire(key, seconds); } }); } public Long incr(final String key) { return execute(key, new RedisExecutor() { @Override public Long execute(Jedis jedis) { return jedis.incr(key); } }); } public Long decr(final String key) { return execute(key, new RedisExecutor() { @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() { @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() { @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() { @Override public Long execute(Jedis jedis) { return jedis.hdel(key, field); } }); } public String hmset(final String key, final Map hash) { return execute(key, new RedisExecutor() { @Override public String execute(Jedis jedis) { return jedis.hmset(key, hash); } }); } public List hmget(final String key, final String... fields) { return execute(key, new RedisExecutor>() { @Override public List execute(Jedis jedis) { return jedis.hmget(key, fields); } }); } public Long del(final String key) { return execute(key, new RedisExecutor() { @Override public Long execute(Jedis jedis) { return jedis.del(key); } }); } public Map hgetAll(final String key) { return execute(key, new RedisExecutor>() { @Override public Map execute(Jedis jedis) { return jedis.hgetAll(key); } }); } public void destroy() { for (int i = 0; i < jedisPools.length; i++) { jedisPools[i].close(); } } }