redisson实现分布式锁(支持redis单例/集群)


前言

还是在工作中遇到的问题:
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:pppp
    password: 123456
    serializer: json
    jedis:
      pool:
        max-active: 20
        max-idle: 20
        max-wait: 2000ms
        time-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;


    @Autowired
    private 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;
    }

猜你喜欢

转载自blog.csdn.net/qq_37700773/article/details/134639731