/*
* Copyright (c) 2016, S.F. Express Inc. All rights reserved.
*/
package com.sf.novatar.tpl.redis.util;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.*;
/**
* 描述:redis 工具类
*
* <pre>
* HISTORY
* ****************************************************************************
* ID DATE PERSON REASON
* 1 2016年8月8日 Create
* ****************************************************************************
* </pre>
*
* @author
* @since 1.0
*/
@Component
public class RedisUtil {
private final static Logger logger = LoggerFactory
.getLogger(RedisUtil.class);
@Value(value = "${REDIS_ADDR}")
private String redis_addr;
@Value(value = "${REDIS_SENTINEL}")
private String redis_sentinel;
@Value(value = "${REDIS_CLUSTERNAME}")
private String redis_clustername;
@Value(value = "${REDIS_AUTH}")
private String redis_auth;
@Value(value = "${REDIS_MAX_ACTIVE}")
private String redis_max_active;
@Value(value = "${REDIS_MAX_IDLE}")
private String redis_max_idle;
@Value(value = "${REDIS_MAX_WAIT}")
private String redis_max_wait;
@Value(value = "${REDIS_TIMEOUT}")
private String redis_timeout;
private static JedisPool jedisPool = null;
private static JedisSentinelPool redisSentinelJedisPool = null;
@PostConstruct
private void initJedisPool() {
try {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(redis_max_active));
config.setMaxIdle(Integer.parseInt(redis_max_idle));
config.setMaxWaitMillis(Integer.parseInt(redis_max_wait));
// 在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的
config.setTestOnBorrow(true);
// 哨兵模式
if ("true".equalsIgnoreCase(redis_sentinel)) {
Set<String> sentinels = getRedisSentinels(redis_addr);
redisSentinelJedisPool = new JedisSentinelPool(
redis_clustername, sentinels, config, redis_auth);
} else {
String address = redis_addr.split(":")[0];
String port = redis_addr.split(":")[1];
jedisPool = new JedisPool(config, address,
Integer.parseInt(port),
Integer.parseInt(redis_timeout), redis_auth);
}
} catch (Exception e) {
if (logger.isInfoEnabled()) {
logger.info(e.getMessage());
}
e.printStackTrace();
}
}
private Set<String> getRedisSentinels(String redis_addr2) {
Set<String> sentinelSet = new HashSet<String>();
for (String sentinel : redis_addr2.split("\\|")) {
sentinelSet.add(sentinel);
}
return sentinelSet;
}
@PreDestroy
private void destroyJedisPool() {
if ("true".equalsIgnoreCase(redis_sentinel)) {
if (redisSentinelJedisPool != null) {
redisSentinelJedisPool.destroy();
}
} else {
if (jedisPool != null) {
jedisPool.destroy();
}
}
}
/**
* 获取Jedis实例
*
* @return
*/
public synchronized static Jedis getJedis() {
Jedis resource = null;
if (jedisPool != null) {
try {
resource = jedisPool.getResource();
} catch (Throwable t) {
if (resource != null) {
resource.close();
resource = null;
}
}
} else if (redisSentinelJedisPool != null) {
try {
resource = redisSentinelJedisPool.getResource();
} catch (Throwable t) {
if (resource != null) {
resource.close();
resource = null;
}
}
}
return resource;
}
/**
* 释放jedis资源
*
* @param jedis
*/
public static void returnResource(final Jedis jedis) {
if (jedis != null) {
jedis.close();
}
}
public static void set(String key, String value) {
Jedis jedis = null;
try {
jedis = getJedis();
jedis.set(key, value);
} catch (Exception e) {
logger.info(e.getMessage());
} finally {
returnResource(jedis);
}
}
public static void append(String key, String value) {
Jedis jedis = null;
try {
jedis = getJedis();
jedis.append(key, value);
} catch (Exception e) {
logger.info(e.getMessage());
} finally {
returnResource(jedis);
}
}
public static Long del(String key) {
Jedis jedis = null;
try {
jedis = getJedis();
return jedis.del(key);
} catch (Exception e) {
logger.info(e.getMessage());
return null;
} finally {
returnResource(jedis);
}
}
public static String get(String key) {
Jedis jedis = null;
try {
jedis = getJedis();
return jedis.get(key);
} catch (Exception e) {
logger.info(e.getMessage());
return "";
} finally {
returnResource(jedis);
}
}
/**
* 设置值 并加上过期
*
* @param key
* @param value
* @param seconds
*/
public static void setAndExpire(String key, String value, int seconds) {
Jedis jedis = null;
try {
jedis = getJedis();
jedis.set(key, value);
jedis.expire(key, seconds);
} catch (Exception e) {
logger.info(e.getMessage());
} finally {
returnResource(jedis);
}
}
/**
* 移除锁
*
* @param jedis
* Jedis 客户端
* @param lockName
* 锁名字,会加上前缀“lock:”
* @param identifier
* 锁的标识
* @return 是否移除成功
*/
public static boolean releaseLock(Jedis jedis, String lockName,
String identifier) {
lockName = String.format("lock:%s", lockName);
while (true) {
jedis.watch(lockName);
if (identifier.equals(jedis.get(lockName))) {
Transaction tx = jedis.multi();
tx.del(lockName);
List<Object> list = tx.exec();
jedis.unwatch();
if (list == null) {
continue;
}
return true;
} else {
jedis.unwatch();
break;
}
}
return false;
}
/**
* 移除锁
*
* @param lockName
* 锁名字,会加上前缀“lock:”
* @param identifier
* 锁的标识
* @return 是否移除成功
*/
public static boolean releaseLock(String lockName, String identifier) {
Jedis jedis = RedisUtil.getJedis();
boolean re;
try {
re = RedisUtil.releaseLock(jedis, lockName, identifier);
} finally {
RedisUtil.returnResource(jedis);
}
return re;
}
/**
* 获取锁
*
* @param jedis
* Jedis 客户端
* @param lockName
* 锁名字,会加上前缀“lock:”
* @param acquireTimeout
* 获取锁,重试时间(毫秒)
* @param lockTimeout
* 锁的自动过期时间(秒)
* @return 锁的标识
*/
public static String acquireLockWithTimeout(Jedis jedis, String lockName,
int acquireTimeout, int lockTimeout) {
String identifier = UUID.randomUUID().toString();
lockName = String.format("lock:%s", lockName);
long end = System.currentTimeMillis() + acquireTimeout;
do {
if (jedis.setnx(lockName, identifier) == 1) {
jedis.expire(lockName, lockTimeout);
return identifier;
} else if (jedis.ttl(lockName) == -1) {
jedis.expire(lockName, lockTimeout);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
} while (System.currentTimeMillis() < end);
return null;
}
/**
* 获取锁
*
* @param lockName
* 锁名字,会加上前缀“lock:”
* @param acquireTimeout
* 获取锁,重试时间(毫秒)
* @param lockTimeout
* 锁的自动过期时间(秒)
* @return 锁的标识
*/
public static String acquireLockWithTimeout(String lockName,
int acquireTimeout, int lockTimeout) {
Jedis jedis = RedisUtil.getJedis();
String identifier;
try {
identifier = RedisUtil.acquireLockWithTimeout(jedis, lockName,
acquireTimeout, lockTimeout);
} finally {
RedisUtil.returnResource(jedis);
}
return identifier;
}
}
RedisUtil(哨兵模式)
最新推荐文章于 2024-07-30 10:52:32 发布