applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--加载外部资源-->
<context:property-placeholder location="classpath:jedis.properties"/>
<context:component-scan base-package="com.xxx.jedis"/>
</beans>
jedis.properties
jedis.host = 192.168.xx.xx
jedis.port = 6379
配置类:
package com.xxx.jedis.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class AppConfig implements ApplicationContextAware{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
分布式锁工具类:
package com.xxx.jedis.utils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.SetParams;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@Component
public class RedisDistributeLock {
private static final String LOCK_SUCCESS = "OK";
private static final String RELEASE_SUCCESS = "1";
// 可用连接实例最大数目,默认为8;如果赋值为-1,则表示不限制,如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
private static final Integer MAX_TOTAL = 1024;
// 控制一个pool最多有多少个状态为idle(空闲)的jedis实例,默认值为8
private static final Integer MAX_IDLE = 200;
// 集群配置,地址:端口
private static String nodeAddress;
// 密码
private static String password;
private static JedisCluster jedisCluster = null;
private static Environment env = AppConfig.getApplicationContext().getEnvironment();
private static String getProperties(String key) {
return env.getProperty(key);
}
static {
try {
nodeAddress = getProperties("redis.redisClusterConfig.clusters");
password = getProperties("redis.redisClusterConfig.password");
String[] nodeArr = nodeAddress.split(",");
Set<HostAndPort> nodes = new HashSet<>();
for (int i = 0; i < nodeArr.length; i++) {
String address = nodeArr[i];
String[] split = address.split(":");
String host = split[0];
int post = Integer.parseInt(split[1]);
nodes.add(new HostAndPort(host, post));
}
// 创建jedis池实例
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(MAX_TOTAL);
config.setMaxIdle(MAX_IDLE);
jedisCluster = new JedisCluster(nodes, 1000, 1000, 3, password, config);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取锁
* @param lockKey
* @param requestId
* @param expireTime
* @return
*/
public static boolean tryLock(String lockKey, String requestId, int expireTime) {
// 如果redis获取失败,直接返回成功,不影响业务逻辑
if (jedisCluster == null) {
return true;
}
// nx,不存在则设置成功,否则失败
String result = jedisCluster.set(lockKey, requestId, SetParams.setParams().nx().px(expireTime));
return LOCK_SUCCESS.equals(result);
}
/**
* 释放锁
* @param lockKey
* @param requestId
* @return
*/
public static boolean releaseLock(String lockKey, String requestId) {
String lua_scripts = "if redis.call('get',KEYS[1]) == ARGV(1) then return redis.call('del',KEYS[1]) else return 0 end";
Object result = jedisCluster.eval(lua_scripts, Collections.singletonList(lockKey), Collections.singletonList(requestId));
return RELEASE_SUCCESS.equals(result);
}
}