springboot2.0集成哨兵模式Redisson

学习网站:https://my.oschina.net/u/3959468/blog/2251918

1、Redisson

Redisson 是一个在 Redis 的基础上实现的 Java 驻内存数据网格,相较于暴露底层操作的Jedis,Redisson提供了一系列的分布式的 Java 常用对象,还提供了许多分布式服务。

特性 & 功能:

  • 支持 Redis 单节点(single)模式、哨兵(sentinel)模式、主从(Master/Slave)模式以及集群(Redis Cluster)模式

  • 程序接口调用方式采用异步执行和异步流执行两种方式

  • 数据序列化,Redisson 的对象编码类是用于将对象进行序列化和反序列化,以实现对该对象在 Redis 里的读取和存储

  • 单个集合数据分片,在集群模式下,Redisson 为单个 Redis 集合类型提供了自动分片的功能

  • 提供多种分布式对象,如:Object Bucket,Bitset,AtomicLong,Bloom Filter 和 HyperLogLog 等

  • 提供丰富的分布式集合,如:Map,Multimap,Set,SortedSet,List,Deque,Queue 等

  • 分布式锁和同步器的实现,可重入锁(Reentrant Lock),公平锁(Fair Lock),联锁(MultiLock),红锁(Red Lock),信号量(Semaphonre),可过期性信号锁(PermitExpirableSemaphore)等

  • 提供先进的分布式服务,如分布式远程服务(Remote Service),分布式实时对象(Live Object)服务,分布式执行服务(Executor Service),分布式调度任务服务(Schedule Service)和分布式映射归纳服务(MapReduce)

  • 更多特性和功能,请关注官网:http://redisson.org

实现原理

redis本身是不支持上述的分布式对象和集合,Redisson是通过利用redis的特性在客户端实现了高级数据结构和特性,例如优先队列的实现,是通过客户端排序整理后再存入redis。

客户端实现,意味着当没有任何客户端在线时,这些所有的数据结构和特性都不会保留,也不会自动生效,例如过期事件的触发或原来优先队列的元素增加。

 

2、springboot2.0集成哨兵模式Redisson

代码示例:

1、springboot版本

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.17.RELEASE</version>
        <relativePath/>
    </parent>

2、引入redis和redisson,这里要注意,如果redssion使用3.12以下程序运行报错。

        <!--redis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--redisson-->
        <dependency>
            <groupId>org.redisson</groupId>
            <artifactId>redisson-spring-boot-starter</artifactId>
            <version>3.12.0</version>
        </dependency>

3、配置redis配置参数,properties,本文是哨兵模式的redis配置

#连接池配置
spring.redis.jedis.pool.max-idle = 16
spring.redis.jedis.pool.min-idle = 8
spring.redis.jedis.pool.max-active = 8
spring.redis.jedis.pool.max-wait = 3000
spring.redis.pool.conn-timeout = 3000
spring.redis.pool.so-timeout = 3000
spring.redis.pool.size = 10
spring.redis.sentinel.master-onlyWrite = true
spring.redis.sentinel.fail-max = 3

#配置哨兵模式redis连接信息
spring.redis.sentinel.master = xxxx
spring.redis.sentinel.nodes = ip:port,ip:port
spring.redis.password = xxxx
spring.redis.database = xxxx

 

4、配置Redisson配置类


import org.apache.commons.lang.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.ReadMode;
import org.redisson.config.SentinelServersConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class RedissonConfig {

    @Value("${spring.redis.sentinel.nodes}") private String nodes;

    @Value("${spring.redis.sentinel.master}") private String master;

    @Value("${spring.redis.sentinel.fail-max}") private int failMax;

    @Value("${spring.redis.pool.conn-timeout}") private int timeout;

    @Value("${ spring.redis.pool.size}") private int size;

    @Value("${spring.redis.password}") private String password;


    //哨兵模式配置
    @Bean
    RedissonClient redissonSentinel() {
        Config config = new Config();
        String[] nodeStr = nodes.split(",");
        List<String> newNodes = new ArrayList(nodeStr.length);
        Arrays.stream(nodeStr).forEach((index) -> newNodes.add(
                index.startsWith("redis://") ? index : "redis://" + index));

        SentinelServersConfig serverConfig = config.useSentinelServers()
                .addSentinelAddress(newNodes.toArray(new String[0]))
                .setMasterName(master)
                .setReadMode(ReadMode.SLAVE)
                .setFailedAttempts(failMax)
                .setTimeout(timeout)
                .setMasterConnectionPoolSize(size)
                .setSlaveConnectionPoolSize(size);

        if (StringUtils.isNotBlank(password)) {
            serverConfig.setPassword(password);
        }
        return Redisson.create(config);
    }

}

5、测试lock

@Autowired RedissonClient redisson;

@Test
public void testLock() {
    //创建实例对象
    RLock lock = redisson.getLock("newlock");
    
    //当前是否有锁
    boolean locked = lock.isLocked();
    if(locked){
        //有锁直接return
        return;
    }
    //上锁
    lock.lock();
    //TODO 执行逻辑
    //执行完毕释放锁
    lock.unlock();
}
public void lock(String name) throws InterruptedException {
        //获得name的锁
        RLock lock = redissonClient.getLock(name);
        //对name进行加锁 线程会一直等待 直到拿到该锁
        lock.lock();
        //尝试对name进行加锁,线程会一直等待 直到拿到该锁 然后10秒后自动解锁
        lock.lock(10L,TimeUnit.SECONDS);
        //对name进行解锁,如果锁不是该线程持有则会抛出异常
        lock.unlock();
        //强制对name进行解锁,即此锁不论是那个线程持有都会进行解锁
        lock.forceUnlock();
 
        //尝试对name进行加锁,如果该锁被其他线程持有,会等待10秒,然后返回是否成功,如果成功 会在20秒后自动解锁
        boolean b = lock.tryLock(10L, 20L, TimeUnit.SECONDS);
 
        //尝试对name进行加锁 立即返回加锁状态 如果加锁成功会在20秒后自动解锁
        boolean b1 = lock.tryLock(20L, TimeUnit.SECONDS);
        //检查该锁是否被任何线程所持有
        boolean locked = lock.isLocked();
        //检查该锁是否当前线程持有
        boolean heldByCurrentThread = lock.isHeldByCurrentThread();
        //当前线程对该锁的保持次数
        int holdCount = lock.getHoldCount();
        //该锁的剩余时间
        long l = lock.remainTimeToLive();
    }

感谢观看

 

 

 

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值