zoukankan      html  css  js  c++  java
  • SpringBoot 2.0集成Redisson实现分布式锁(redis-cluster集群模式 与 单机模式)

    一般提及到Redis的分布式锁我们更多的使用的是Redisson的分布式锁,Redis的官方也是建议我们这样去做的。Redisson点我可以直接跳转到Redisson的官方文档。

    Redisson概述

     
     

    Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。

    关于Redisson项目的详细介绍可以在官方网站找到。

    每个Redis服务实例都能管理多达1TB的内存。

    能够完美的在云计算环境里使用,并且支持AWS ElastiCache主备版AWS ElastiCache集群版Azure Redis Cache阿里云(Aliyun)的云数据库Redis版

    以下是Redisson的结构:

    Redisson作为独立节点 可以用于独立执行其他节点发布到分布式执行服务 和 分布式调度任务服务 里的远程任务。

     
     

    如果你现在正在使用其他的Redis的Java客户端,那么Redis命令和Redisson对象匹配列表 能够帮助你轻松的将现有代码迁徙到Redisson框架里来。

    Redisson底层采用的是Netty 框架。支持Redis 2.8以上版本,支持Java1.6+以上版本。

    1、引入Maven依赖

    <!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
    <dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.12.2</version>
    </dependency>

    2、配置redis信息

    单机模式

    spring:
      redis:
        port: 6379
        host: 127.0.0.1
        password: ******
        database: 0
        timeout: 2000

    集成模式:

    spring:
      redis:
        cluster:
          nodes: "192.168.1.11:7000,192.168.1.12:7000,192.168.1.12:7001"
        password: ******
        lettuce:
          pool:
            max-active: 1500
            max-wait: 5000
            max-idle: 500
            min-idle: 100
            shutdown-timeout: 1000
        timeout: 60000

    3、增加一个RedisConfigProperties用于读取配置文件信息

    单机模式

    /**
     * redisson 配置类
     * Created on 2018/6/19
     */
    @Configuration
    public class RedissonConfig {
        @Value("${spring.redis.host}")
        private String host;
    @Value(
    "${spring.redis.port}") private String port;
    @Value(
    "${spring.redis.password}") private String password; @Bean public RedissonClient getRedisson(){ Config config = new Config(); config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password); //添加主从配置 // config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""}); return Redisson.create(config); } }

    集成模式

    @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;
        }
    }
    @Configuration
    public class RedissonConfig {
        @Autowired
        private RedisConfigProperties redisConfigProperties;
    
        @Bean
        public RedissonClient redissonClient() {
            //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());
            RedissonClient redissonClient = Redisson.create(config);
            return redissonClient;
        }
    }

    4、测试调用

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

    其实Redisson还有其他好多的方法来解决现在互联网中的好多问题,大家如果想了解更多的东西,可以去Redisson官网。

    Redisson官网:

     参考:

    https://www.cnblogs.com/milicool/p/9201271.html

    https://www.cnblogs.com/zengnansheng/p/11426996.html

    https://www.jianshu.com/p/3f3c3c733f32

  • 相关阅读:
    从最近面试聊聊我所感受的职业天花板
    NetCore基于EasyNetQ的高级API使用RabbitMq
    Ocelot学习笔记
    使用iis反向代理.net core应用程序
    Odoo 部署windows server 2012
    低版本VMware与docker不兼容
    odoo tools
    Pandas 学习随笔
    Json数据校验 Json Schema
    python入门
  • 原文地址:https://www.cnblogs.com/fightingtong/p/12360222.html
Copyright © 2011-2022 走看看