分布式锁2:基于redis的插件redission实现分布式锁

一  redision简介

1.1 redission介绍

Redisson分布式锁是一种基于redis实现的分布式锁,它利用redis的setnx命令实现分布式锁的互斥访问。同时还支持锁的自动续期功能,可以避免因为某个进程崩溃或者网络故障导致锁无法释放的情况。

只要线程一加锁成功,就会启动一个watchdog看门狗,它是一个后台线程,会每隔10秒检查一下,默认生存时间只有30秒如果线程A还持有锁,那么就会不断的延长锁key的生存时间。可以使用reentracklock,公平锁,读写锁,信号量,闭锁等锁进行加锁操作,完成后然后释放锁。其他线程BCD判断加锁的次数为0,就可以进行加锁操作。

因此,Redisson就是使用watch dog解决了「锁过期释放,业务没执行完问题。

如果使用这个分布式锁的Redisson节点实例客户端宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。

1.2  常用锁介绍

1.2.1 重入锁

基于Redis的Redisson分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口。 Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。

1.2.2 公平锁

它保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson会等待5秒后继续下一个线程,也就是说如果前面有5个线程都处于等待状态,那么后面的线程会等待至少25秒。

1.2.3 联锁

基于Redis的Redisson分布式联锁RedissonMultiLock对象可以将多个RLock对象关联为一个联锁,每个RLock对象实例可以来自于不同的Redisson实例。要求每一个节点都得满足。则获取锁成功

1.2.4 redlock 红锁

基于Redis的Redisson红锁RedissonRedLock对象实现了Redlock介绍的加锁算法。该对象也可以用来将多个RLock对象关联为一个红锁,每个RLock对象实例可以来自于不同的Redisson实例。大部分节点满足则获取锁成功

1.2.5 信号量

基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)反射式(Reactive)RxJava2标准的接口。

1.2.6 读写锁

分布式可重入读写锁允许同时有多个读锁和一个写锁处于加锁状态。

1.2.7 闭锁

1.3  案例操作

1.3.1 pom依赖配置

1.3.2 redisson配置文件

package com.atguigu.distributed.lock.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @ClassName: RedissonConfig
 * @Description: TODO
 * @Author: admin
 * @Date: 2024/01/14 23:18:50 
 * @Version: V1.0
 **/
@Configuration
public class RedissonConfig {

    @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        // 可以用"rediss://"来启用SSL连接
     //   config.useSingleServer().setAddress("redis://192.168.43.4:6379");
        config.useSingleServer().setAddress("redis://192.168.43.4:6379").setPassword("123456");
        return Redisson.create(config);
    }
}

1.3.3  核心加锁代码

    @Autowired
    private RedissonClient redissonClient;

    public void checkAndLockByRedisson() {
        // 加锁,获取锁失败重试
        RLock lock = this.redissonClient.getLock("rlock");
        lock.lock();
        System.out.println("redisson的锁....");
        // 先查询库存是否充足
        Stock stock = this.stockMapper.selectById(1L);
        // 再减库存
        if (stock != null && stock.getCount() > 0){
            stock.setCount(stock.getCount() - 1);
            this.stockMapper.updateById(stock);
        }
        // 释放锁
        lock.unlock();
    }

1.3.4  controller调用

1.3.5  验证调试

1.启动服务

2.启动redis

[root@localhost export]# redis-server /myredis/redis.conf
[root@localhost export]# redis-cli -a 123456 -p 6379

3.启动zk

[root@localhost export]# cd apache-zookeeper-3.7.0-bin/
[root@localhost apache-zookeeper-3.7.0-bin]# cd bin
[root@localhost bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /root/export/apache-zookeeper-3.7.0-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

4.启动nginx

5.启动jemter

6.查看结果

2.查看结果

7.查看db结果

测试前

测试后

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值