分布式锁

分布式锁

###基本概念
我们在开发单体应用的时候,如果遇到多线程同步访问某个方法时,只需要非常简单的加锁处理即可保证数据的正确性,那如果集群部署的时候,比如在线上执行一个定时任务,两边同时执行了你的任务,导致数据错乱,甚至造成更大损失。那么分布式锁到底该用在哪些场景,分布式锁应该具备什么条件呢?
1.在分布式环境下,一个方法只能被其中一台机器单线程执行
2.锁要有可重入性
3.锁失效机制,防止死锁,如果获取不到锁,直接返回失败

###常用分布式锁

1.数据库分布式锁
这种锁,有一定的缺陷,首先是性能问题。其次需要写很多逻辑去处理,而且过程中会出现很多问题,实现方式:创建一张表,要使用就把方法名插入进数据库,从而获得锁,执行完成删除数据
2.redis 手动分布式锁 主要是NX的实现,过程比较复杂,释放锁,需要写lua脚本,不推荐
3.zookeeper分布式锁 更加复杂,不推荐





4.zookeeper的curator客户端 唯一的缺陷是基于zookeeper
这个写一下,毕竟好用

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>

/***
*注册CuratorFramework
*/
@Component
public class CuratorLockConf {
    @Bean(initMethod = "start",destroyMethod = "close")
    public CuratorFramework getFramework(){
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", retryPolicy);
        return client;
    }
}






@Autowired
private  CuratorFramework client;

@RequestMapping("cc")
public String curatorLock(){
    log.info("进入方法");
    InterProcessMutex lock = new InterProcessMutex(client,"/order" );
    try {
        if (lock.acquire(30, TimeUnit.MINUTES)){
            try {
                log.info("获得了锁");
                Thread.sleep(1000);
            }finally {
                log.info("释放了锁");
                lock.release();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "Ok";
}

接下来是我们平时项目中用到最多的一种锁 redisson

5.redissonApi方式

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson</artifactId>
    <version>3.13.3</version>
</dependency>

@RequestMapping("RedissonApiLock")
public String RedissonApiLock(){
    Config config = new Config();
    config.useSingleServer().setAddress("redis://192.168.1.200:9379").setPassword("root@123456").setDatabase(3);
    RedissonClient redissonClient = Redisson.create(config);
    RLock order = redissonClient.getLock("order");
    log.info("进入了方法");
    try {
        order.lock(30,TimeUnit.SECONDS);//过期时间,如果没有释放锁,超出时间会自动释放
        log.info("获得了锁");
        Thread.sleep(1000);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        log.info("释放了锁");
        order.unlock();
    }
    return "Ok";
}

6.redisson-spring-boot-start 用到最多的方法

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.13.3</version>
</dependency>

@Autowired
private  RedissonClient redissonClient;

@RequestMapping("RedissonLock")
public String RedissonLock(){
    RLock order = redissonClient.getLock("order");
    log.info("进入了方法");
    try {
        order.lock(30,TimeUnit.SECONDS);//过期时间,如果没有释放锁,超出时间会自动释放
        log.info("获得了锁");
        Thread.sleep(1000);
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        log.info("释放了锁");
        order.unlock();
    }
    return "Ok";
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值