美文网首页
SpringBoot整合Redisson实现分布式锁

SpringBoot整合Redisson实现分布式锁

作者: salt丶 | 来源:发表于2020-08-09 12:18 被阅读0次

    用Redisson框架实现Redis分布式锁

    B站视频教学:https://www.bilibili.com/video/BV1np4y1i7DE?p=1

    Redisson特性介绍

    博客:https://www.jianshu.com/p/43cfa79e62a5

    SpringBoot整合Redisson集群模式:

    原文摘自:https://www.cnblogs.com/zengnansheng/p/11426996.html

    1. maven依赖
    <!-- redis-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!--springboot2.0的redis整合包多出lettuce连接池,需要增加commons-pool2包
    1.5的版本默认采用的连接池技术是jedis  2.0以上版本默认连接池是lettuce
    spring boot 2.0 的操作手册有标注 大家可以去看看 地址是:https://docs.spring.io/spring-boot/docs/2.0.3.RELEASE/reference/htmlsingle-->
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-pool2</artifactId>
        <version>2.4.2</version>
    </dependency>
    
    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redisson</artifactId>
        <version>3.6.5</version>
    </dependency>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.25.Final</version>
    </dependency>
     <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
     </dependency>
    
    1. yml配置
    redis:
        timeout: 6000ms
        password: '123456'
        cluster:
          max-redirects: 3  # 获取失败 最大重定向次数
          nodes:
            - 192.168.182.129:7001
            - 192.168.182.129:7002
            - 192.168.182.129:7003
            - 192.168.182.129:7004
            - 192.168.182.129:7005
            - 192.168.182.129:7006
        lettuce:
          pool:
            max-active: 1000  #连接池最大连接数(使用负值表示没有限制)
            max-idle: 10 # 连接池中的最大空闲连接
            min-idle: 5 # 连接池中的最小空闲连接
            max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
    
    1. 增加一个RedisConfigProperties用于读取配置文件信息
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;
    import java.util.List;
    
    @Component
    @ConfigurationProperties(prefix = "spring.redis")
    public class RedisConfigProperties {
        private String password;
        private cluster cluster;
    
        public static class cluster {
            private List<String> nodes;
    
            public List<String> getNodes() {
                return nodes;
            }
    
            public void setNodes(List<String> nodes) {
                this.nodes = nodes;
            }
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public RedisConfigProperties.cluster getCluster() {
            return cluster;
        }
    
        public void setCluster(RedisConfigProperties.cluster cluster) {
            this.cluster = cluster;
        }
    }
    
    1. 增加RedissonConfig
    import com.zns.properties.RedisConfigProperties;
    import org.redisson.Redisson;
    import org.redisson.config.ClusterServersConfig;
    import org.redisson.config.Config;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import java.util.ArrayList;
    import java.util.List;
    
    @Configuration
    public class RedissonConfig {
        @Autowired
        private RedisConfigProperties redisConfigProperties;
    
        //添加redisson的bean
        @Bean
        public Redisson redisson() {
            //redisson版本是3.5,集群的ip前面要加上“redis://”,不然会报错,3.2版本可不加
            List<String> clusterNodes = new ArrayList<>();
            for (int i = 0; i < redisConfigProperties.getCluster().getNodes().size(); i++) {
                clusterNodes.add("redis://" + redisConfigProperties.getCluster().getNodes().get(i));
            }
            Config config = new Config();
            ClusterServersConfig clusterServersConfig = config.useClusterServers()
                    .addNodeAddress(clusterNodes.toArray(new String[clusterNodes.size()]));
            clusterServersConfig.setPassword(redisConfigProperties.getPassword());//设置密码
            return (Redisson) Redisson.create(config);
        }
    }
    
    1. 测试类:
    import org.redisson.Redisson;
    import org.redisson.api.RLock;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.concurrent.Future;
    import java.util.concurrent.TimeUnit;
    
    @RestController
    @RequestMapping("")
    public class RedisLockController {
        private static String product1Count = "product1Count";//商品1的数量key
        private static String lockKey = "testLockKey";//分布式锁的key
        @Autowired
        private StringRedisTemplate redisTemplate;
        @Autowired
        private Redisson redisson;
    
        /**
         * 初始化设置商品数量
         *
         * @return
         */
        @RequestMapping("/setProductCount")
        public String setValue() {
            redisTemplate.opsForValue().set(product1Count, "100");
            return "success";
        }
    
        /**
         * 模拟秒杀抢购,并发多个请求过来,查看是否出现超卖
         *
         * @return
         */
        @RequestMapping("/spike")
        public String spike() {
            String flag = "success";
            RLock lock = redisson.getLock(lockKey);
            try {
                //lock.lockAsync(5 , TimeUnit.SECONDS);
                //lock.lock(5, TimeUnit.SECONDS); //设置60秒自动释放锁  (默认是30秒自动过期)
                Future<Boolean> res = lock.tryLockAsync(100, 5, TimeUnit.SECONDS);
                boolean result = res.get();
                System.out.println("result:" + result);
                if (result) {
                    int stock = Integer.parseInt(redisTemplate.opsForValue().get(product1Count).toString());
                    if (stock > 0) {
                        redisTemplate.opsForValue().set(product1Count, (stock - 1) + "");
                    } else {
                        flag = "fail";
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); //释放锁
            }
            return flag;
        }
    }
    

    SpringBoot整合Redisson单机模式

    对上面第四点RedissonConfig进行修改:

    @Bean
        public Redisson RedissonConfig(){
            Config config = new Config();
            config.useSingleServer().setAddress("redis://localhost:6379").setDatabase(0);
            return (Redisson) Redisson.create(config);
        }
    

    相关文章

      网友评论

          本文标题:SpringBoot整合Redisson实现分布式锁

          本文链接:https://www.haomeiwen.com/subject/vnrjrktx.html