代码如下:
/**
* redis相关的操作助手
*/
@SuppressWarnings("SpellCheckingInspection")
public class RedisHelper {
private static CommonLog log = CommonLog.getInstance(LoggerFactory.getLogger(RedisHelper.class));
/**
* SetNx luava脚本原子命令,Redis分布式锁setnx后setexpire因某种问题导致没执行,导致锁一直被占的问题
*/
public final static String SET_NX_SCRIPT = "" +
"local rs=redis.call('setnx',KEYS[1],ARGV[1]);" +
"if(rs<1) then return 'F';end;" +
"redis.call('expire',KEYS[1],tonumber(ARGV[2]));" +
"return 'S';";
private static JedisPool jedisPool = null;
static {
try {
// 数据库链接池配置
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数, 应用自己评估,不要超过Redis每个实例最大的连接数 10000
config.setMaxTotal(9000);
//最大空闲连接数, 应用自己评估,不要超过Redis每个实例最大的连接数
config.setMaxIdle(50);
//最小能够保持Idle状态的对象数
config.setMinIdle(20);
//当池内没有返回对象时,最大等待时间
config.setMaxWaitMillis(6 * 1000);
config.setTestOnBorrow(false);
config.setTestOnReturn(false);
String path = PathConstant.CONFIG_PATH + "redis-anxuan.properties";
PropertiesHelper helper = new PropertiesHelper(path);
jedisPool = new JedisPool(config, helper.getString("host"), helper.getInt("port"), 3000, helper.getString("password"));
} catch (Exception e) {
log.error("", "JedisPool startup error", "JedisPool初始化异常:{}", e.getMessage(), e);
}
}
public static Jedis getJedis() {
if (jedisPool != null) {
return jedisPool.getResource();
}
throw new IllegalStateException("JedisPool has not successfully initialized!");
}
public static void set(String key, String value) {
Jedis jedis = getJedis();
try {
if (StringUtils.isNotBlank(key)) {
jedis.set(key, value);
}
} catch (Exception e) {
log.error("", "RedisHelper-set-exception", "异常:{}", e.getMessage(), e);
} finally {
releaseResource(jedis);
}
}
/**
* 写入值
*
* @param key key
* @param value value
* @param ttlSeconds 过期时长(秒)
*/
public static void setex(String key, String value, int ttlSeconds) {
Jedis jedis = getJedis();
try {
if (StringUtils.isNotBlank(key)) {
jedis.setex(key, ttlSeconds, value);
}
} catch (Exception e) {
log.error("", "RedisHelper-setex-exception", "异常:{}", e.getMessage(), e);
} finally {
releaseResource(jedis);
}
}
public static String get(String key) {
Jedis jedis = getJedis();
try {
if (StringUtils.isNotBlank(key) && jedis.exists(key)) {
return jedis.get(key);
}
} catch (Exception e) {
log.error("", "RedisHelper-get-exception", "异常:{}", e.getMessage(), e);
} finally {
releaseResource(jedis);
}
return null;
}
/**
* 判断Key是否存在
*
* @return boolean
*/
public static boolean exists(String key) {
Jedis jedis = getJedis();
try {
if (StringUtils.isNotBlank(key)) {
return jedis.exists(key);
}
} catch (Exception e) {
log.error("", "RedisHelper-exists-exception", "异常:{}", e.getMessage(), e);
} finally {
releaseResource(jedis);
}
return false;
}
/**
* 释放Jedis连接
*
* @param jedis jedis
*/
public static void releaseResource(Jedis jedis) {
try {
if (jedis != null && jedis.isConnected()) {
jedis.close();
}
} catch (Exception e) {
log.error("", "RedisHelper-releaseResource-exception", "异常:{}", e.getMessage(), e);
}
}
/**
* 定时任务分布式锁(通过luava脚本实现)
*
* @param lockKey 分布式锁的Key
* @param ttlSeconds 过期时长(单位:秒)
*/
public static boolean tryTimingTaskLock(String lockKey, int ttlSeconds) {
if (ttlSeconds <= 0) {
throw new IllegalArgumentException("定时任务分布式锁的过期时长[ttlSeconds]必须为正整数!");
}
Jedis jedis = getJedis();
try {
Object result = jedis.eval(SET_NX_SCRIPT, Collections.singletonList(lockKey), Arrays.asList("1", String.valueOf(ttlSeconds)));
return "S".equals(result);
// 已存在返回0;不存在写入成功返回1(这种写法,有的情况下会出现问题,jedis.expire操作失败,导致锁一直被占用);
/* if (jedis != null && jedis.setnx(lockKey, "1") == 1) {
jedis.expire(lockKey, ttlSeconds);
return true;
}*/
} catch (Exception e) {
log.error("RedisHelper-tryLock-exception:{}", e.getMessage(), e);
} finally {
releaseResource(jedis);
}
return false;
}
}
参考文章:https://blog.csdn.net/cts529269539/article/details/82901314