1、Redisson工具类
public class RedissonUtil {
private RedissonManager redissonManager;
private Redisson redisson;
public RedissonUtil(RedissonManager redissonManager) {
this.redissonManager = redissonManager;
this.redisson = redissonManager.getRedisson();
}
public RedissonUtil() {}
/**
* 加锁操作 (设置锁的有效时间)
* @param lockName 锁名称
* @param leaseTime 锁有效时间
*/
public void lock(String lockName, long leaseTime) {
RLock rLock = redisson.getLock(lockName);
rLock.lock(leaseTime, TimeUnit.SECONDS);
}
/**
* 加锁操作 (锁有效时间采用默认时间30秒)
* @param lockName 锁名称
*/
public void lock(String lockName) {
RLock rLock = redisson.getLock(lockName);
rLock.lock();
}
/**
* 加锁操作 (锁有效时间采用默认时间30秒)
* @param lockName 锁名称
*/
public boolean lock1(String lockName) {
RLock rLock = redisson.getLock(lockName);
try {
return rLock.tryLock(9, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
/**
* 加锁操作(tryLock锁,没有等待时间)
* @param lockName 锁名称
* @param leaseTime 等待时间
*/
public boolean tryLock(String lockName, long waitTime) {
RLock rLock = redisson.getLock(lockName);
boolean getLock = false;
try {
getLock = rLock.tryLock( leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("获取Redisson分布式锁[异常],lockName=" + lockName, e);
e.printStackTrace();
return false;
}
return getLock;
}
/**
* 加锁操作(tryLock锁,有等待时间)
* @param lockName 锁名称
* @param leaseTime 锁有效时间
* @param waitTime 等待时间
*/
public boolean tryLock(String lockName, long leaseTime,long waitTime) {
RLock rLock = redisson.getLock(lockName);
boolean getLock = false;
try {
getLock = rLock.tryLock( waitTime,leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
log.error("获取Redisson分布式锁[异常],lockName=" + lockName, e);
e.printStackTrace();
return false;
}
return getLock;
}
/**
* 解锁
* @param lockName 锁名称
*/
public void unlock(String lockName) {
redisson.getLock(lockName).unlock();
}
/**
* 判断该锁是否已经被线程持有
* @param lockName 锁名称
*/
public boolean isLock(String lockName) {
RLock rLock = redisson.getLock(lockName);
return rLock.isLocked();
}
/**
* 判断该线程是否持有当前锁
* @param lockName 锁名称
*/
public boolean isHeldByCurrentThread(String lockName) {
RLock rLock = redisson.getLock(lockName);
return rLock.isHeldByCurrentThread();
}
public RedissonManager getRedissonManager() {
return redissonManager;
}
public void setRedissonManager(RedissonManager redissonManager) {
this.redissonManager = redissonManager;
}
}
2、配置Redisson的配置类
@Configuration
@Slf4j
public class RedissonAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@Order(value = 2)
public RedissonUtil redissonLock(RedissonManager redissonManager) {
RedissonUtil redissonLock = new RedissonUtil(redissonManager);
return redissonLock;
}
@Bean
@ConditionalOnMissingBean
@Order(value = 1)
public RedissonManager redissonManager(RedissonProperties redissonProperties) {
RedissonManager redissonManager = new RedissonManager(redissonProperties);
return redissonManager;
}
}
3、Redisson的属性类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class RedissonProperties {
/**
* redis主机地址,ip:port,有多个用半角逗号分隔
*/
@Value("${spring.redis.host}")
private String address;
/**
* 连接类型,支持standalone-单机节点,sentinel-哨兵,cluster-集群,masterslave-主从
*/
@Value("${spring.redis.redisson.type}")
private String type;
/**
* redis 连接密码
*/
@Value("${spring.redis.password}")
private String password;
/**
* 选取那个数据库
*/
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.port}")
private String port;
public RedissonProperties setPassword(String password) {
this.password = password;
return this;
}
public RedissonProperties setDatabase(int database) {
this.database = database;
return this;
}
4、Redisson管理器类
@Slf4j
public class RedissonManager {
private Config config = new Config();
private Redisson redisson = null;
public RedissonManager() {
}
public RedissonManager(RedissonProperties redissonProperties) {
try {
//通过不同部署方式获得不同cofig实体
config = RedissonConfigFactory.getInstance().createConfig(redissonProperties);
redisson = (Redisson) Redisson.create(config);
} catch (Exception e) {
log.error("Redisson init error", e);
throw new IllegalArgumentException("please input correct configurations," +
"connectionType must in standalone/sentinel/cluster/masterslave");
}
}
public Redisson getRedisson() {
return redisson;
}
/**
* Redisson连接方式配置工厂
* 双重检查锁
*/
static class RedissonConfigFactory {
private RedissonConfigFactory() {
}
private static volatile RedissonConfigFactory factory = null;
public static RedissonConfigFactory getInstance() {
if (factory == null) {
synchronized (Object.class) {
if (factory == null) {
factory = new RedissonConfigFactory();
}
}
}
return factory;
}
/**
* 根据连接类型获取对应连接方式的配置,基于策略模式
*
* @param redissonProperties redis连接信息
* @return Config
*/
Config createConfig(RedissonProperties redissonProperties) {
Preconditions.checkNotNull(redissonProperties);
Preconditions.checkNotNull(redissonProperties.getAddress(), "redisson.lock.server.address cannot be NULL!");
Preconditions.checkNotNull(redissonProperties.getType(), "redisson.lock.server.password cannot be NULL");
Preconditions.checkNotNull(redissonProperties.getDatabase(), "redisson.lock.server.database cannot be NULL");
String connectionType = redissonProperties.getType();
//声明配置上下文
RedissonConfigService redissonConfigService = null;
if (connectionType.equals(RedisConnectionType.STANDALONE.getConnection_type())) {
redissonConfigService = new StandaloneConfigImpl();
} else if (connectionType.equals(RedisConnectionType.SENTINEL.getConnection_type())) {
redissonConfigService = new SentineConfigImpl();
} else if (connectionType.equals(RedisConnectionType.CLUSTER.getConnection_type())) {
redissonConfigService = new ClusterConfigImpl();
} else if (connectionType.equals(RedisConnectionType.MASTERSLAVE.getConnection_type())) {
redissonConfigService = new MasterslaveConfigImpl();
} else {
throw new IllegalArgumentException("创建Redisson连接Config失败!当前连接方式:" + connectionType);
}
return redissonConfigService.createRedissonConfig(redissonProperties);
}
}
}
5、Redisson的策略类获取不同的连接方式类
public interface RedissonConfigService {
/**
* 根据不同的Redis配置策略创建对应的Config
* @param redissonProperties
* @return Config
*/
Config createRedissonConfig(RedissonProperties redissonProperties);
}
6、Redisson的集群方式类
public class ClusterConfigImpl implements RedissonConfigService {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
String[] addrTokens = address.split(",");
//设置cluster节点的服务IP和端口
for (int i = 0; i < addrTokens.length; i++) {
config.useClusterServers()
.addNodeAddress(GlobalConstant.REDIS_CONNECTION_PREFIX.getConstant_value() + addrTokens[i]);
if (StringUtils.isNotBlank(password)) {
config.useClusterServers().setPassword(password);
}
}
log.info("初始化[集群部署]方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("集群部署 Redisson init error", e);
e.printStackTrace();
}
return config;
}
}
7、Redisson主从类
public class MasterslaveConfigImpl implements RedissonConfigService {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
int database = redissonProperties.getDatabase();
String[] addrTokens = address.split(",");
String masterNodeAddr = addrTokens[0];
//设置主节点ip
config.useMasterSlaveServers().setMasterAddress(masterNodeAddr);
if (StringUtils.isNotBlank(password)) {
config.useMasterSlaveServers().setPassword(password);
}
config.useMasterSlaveServers().setDatabase(database);
//设置从节点,移除第一个节点,默认第一个为主节点
List<String> slaveList = new ArrayList<>();
for (String addrToken : addrTokens) {
slaveList.add(GlobalConstant.REDIS_CONNECTION_PREFIX.getConstant_value() + addrToken);
}
slaveList.remove(0);
config.useMasterSlaveServers().addSlaveAddress((String[]) slaveList.toArray());
log.info("初始化[主从部署]方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("主从部署 Redisson init error", e);
e.printStackTrace();
}
return config;
}
}
8、Redisson单机部署类
public class StandaloneConfigImpl implements RedissonConfigService {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
String port = redissonProperties.getPort();
int database = redissonProperties.getDatabase();
String redisAddr = GlobalConstant.REDIS_CONNECTION_PREFIX.getConstant_value() + address +":"+port;
config.useSingleServer().setAddress(redisAddr);
config.useSingleServer().setDatabase(database);
//密码可以为空
if (StringUtils.isNotBlank(password)) {
config.useSingleServer().setPassword(password);
}
log.info("初始化[单机部署]方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("单机部署 Redisson init error", e);
}
return config;
}
}
9、Redisson的哨兵集群类
public class SentineConfigImpl implements RedissonConfigService {
@Override
public Config createRedissonConfig(RedissonProperties redissonProperties) {
Config config = new Config();
try {
String address = redissonProperties.getAddress();
String password = redissonProperties.getPassword();
int database = redissonProperties.getDatabase();
String[] addrTokens = address.split(",");
String sentinelAliasName = addrTokens[0];
//设置redis配置文件sentinel.conf配置的sentinel别名
config.useSentinelServers().setMasterName(sentinelAliasName);
config.useSentinelServers().setDatabase(database);
if (StringUtils.isNotBlank(password)) {
config.useSentinelServers().setPassword(password);
}
//设置sentinel节点的服务IP和端口
for (int i = 1; i < addrTokens.length; i++) {
config.useSentinelServers().addSentinelAddress(GlobalConstant.REDIS_CONNECTION_PREFIX.getConstant_value() + addrTokens[i]);
}
log.info("初始化[哨兵部署]方式Config,redisAddress:" + address);
} catch (Exception e) {
log.error("哨兵部署 Redisson init error", e);
}
return config;
}
}
10、Redisson的配置策略定义
public enum RedisConnectionType {
STANDALONE("standalone", "单节点部署方式"),
SENTINEL("sentinel", "哨兵部署方式"),
CLUSTER("cluster", "集群方式"),
MASTERSLAVE("masterslave", "主从部署方式");
private final String connection_type;
private final String connection_desc;
private RedisConnectionType(String connection_type, String connection_desc) {
this.connection_type = connection_type;
this.connection_desc = connection_desc;
}
public String getConnection_type() {
return connection_type;
}
public String getConnection_desc() {
return connection_desc;
}
}
11、全局参数配置类
public enum GlobalConstant {
REDIS_CONNECTION_PREFIX("redis://", "Redis地址配置前缀");
private final String constant_value;
private final String constant_desc;
GlobalConstant(String constant_value, String constant_desc) {
this.constant_value = constant_value;
this.constant_desc = constant_desc;
}
public String getConstant_value() {
return constant_value;
}
public String getConstant_desc() {
return constant_desc;
}
}
12、pom文件
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
参考
https://blog.csdn.net/u010963948/article/details/79240050.
https://blog.csdn.net/zilong_zilong/article/details/78252037.
https://zhuanlan.zhihu.com/p/135864820.
结束
整理不易,记得点个赞,你的支持是我最大的动力