SpringBoot整合Redisson(集群模式)


環境: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以上版本默認連接池是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>

 
        

增加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請求,最后查看庫存是否為負數,證明分布式鎖是否鎖住了庫存

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM