redisson实现分布式锁
- 前言
- 一、引入redisson依赖
- 二、redis 配置
- 三、redisson 配置
- 1.集群配置
- 2.单例配置
- 四、分布式锁使用-业务层demo
前言
还是在工作中遇到的问题:
1:新增商铺信息时,同一个商铺有多条信息。
异步的情况,根据商铺名和商铺地址作为唯一条件,不加分布式锁就会有重复的商铺信息。
2:代码要发布到云化环境(redis集群) & 一体机环境(redis单例)
使用ConditionalOnProperty注解
一、引入redisson依赖
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.16.2</version></dependency>
二、redis 配置
spring:# redis单例配置
# redis:
# host: 127.0.0.1
# port: 6379
# password: 123456
# serializer: json
# jedis:
# pool:
# max-active: 20
# max-idle: 20
# max-wait: 2000ms
# time-between-eviction-runs: 3000# redis集群配置redis:cluster:nodes: xxx.xxx.xxx.xxx:pppp,xxx.xxx.xxx.xxx:pppp,xxx.xxx.xxx.xxx:pppp,xxx.xxx.xxx.xxx:pppppassword: 123456serializer: jsonjedis:pool:max-active: 20max-idle: 20max-wait: 2000mstime-between-eviction-runs: 30000
三、redisson 配置
1.集群配置
代码如下(示例):
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Slf4j
@Configuration
@ConditionalOnProperty(name = "spring.redis.cluster.nodes")
public class MyRedissonClusterConfig {private static final String REDIS_SSH_URL = "redis://";@Value(value = "${spring.redis.cluster.nodes}")private String host;@Value(value = "${spring.redis.password}")private String password;/*** 所有对redisson的使用都是通过RedissonClient来操作的*/@Bean(destroyMethod = "shutdown")public RedissonClient redisson() {log.info("redisson启动,加载集群");// 1. 创建配置Config config = new Config();// 一定要加redis://String[] hostArr = host.split(",");String[] newHostArr = new String[hostArr.length];for (int i = 0; i < hostArr.length; i++) {newHostArr[i] = REDIS_SSH_URL + hostArr[i];}config.useClusterServers().addNodeAddress(newHostArr);config.useClusterServers().setPassword(password);// 2. 根据config创建出redissonClient实例return Redisson.create(config);}
}
2.单例配置
代码如下(示例):
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Slf4j
@Configuration
@ConditionalOnProperty(name = "spring.redis.host")
public class MyRedissonSingleConfig {private static final String REDIS_SSH_URL = "redis://";@Value(value = "${spring.redis.host}")private String host;@Value(value = "${spring.redis.port}")private String port;@Value(value = "${spring.redis.password}")private String password;/*** 所有对redisson的使用都是通过RedissonClient来操作的**/@Bean(destroyMethod = "shutdown")public RedissonClient redisson() {log.info("redisson启动,加载单例");// 1. 创建配置Config config = new Config();// 一定要加redis://config.useSingleServer().setAddress(REDIS_SSH_URL+ host + ":" + port);config.useSingleServer().setPassword(password);// 2. 根据config创建出redissonClient实例return Redisson.create(config);}
}
该处使用的url网络请求的数据。
四、分布式锁使用-业务层demo
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
@Autowiredprivate RedissonClient redissonClient;@GetMapping("test/lock")public String testLock() {RLock lock = redissonClient.getLock("123");try {//加锁10s,不设置加密狗,不搞死锁。boolean b = lock.tryLock(10, TimeUnit.SECONDS);if (b) {//todo 这里写业务逻辑return "123";}} catch (InterruptedException e) {e.printStackTrace();log.error("分布式锁异常了," + e.getMessage());} finally {lock.unlock();}return null;}