SpringBoot整合Redisson(集群模式)

孤街浪徒 提交于 2019-11-28 20:37:00

环境:SpringBoot2.x

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以上版本默认连接池是lettucespring 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>


增加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 # 连接池最大阻塞等待时间(使用负值表示没有限制)

 

增加一个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;
    }
}

 

增加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);
    }
}

 

模拟测试控制器

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

 

模拟秒杀抢购场景,初始化100库存,用jmeter软件工具测试,设置2秒内启动 300线程,循环请求2次,总计600请求,最后查看库存是否为负数,证明分布式锁是否锁住了库存

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!