• 解决Redis分布式锁宕机出现不可靠问题-zookeeper分布式锁


    核心思想:当客户端要获取锁,则创建节点,使用完锁,则删除该节点。

    1. 客户端获取锁时,在 lock 节点下创建临时顺序节点。
    2. 然后获取 lock下面的所有子节点,客户端获取到所有的子节点之后,如果发现自己创建的子节点序号最小,那么就认为该客户端获取到了锁。使用完锁后,将该节点删除。
    3. 如果发现自己创建的节点并非 lock所有子节点中最小的,说明自己还没有获取到锁。此时客户端需要找到比自己小的那个节点,同时对其注册事件监听器,监听删除事件。
    4. 如果发现比自己小的那个节点被删除,则客户端的 Watcher 会收到相应通知,此时再次判断自己创建的节点:
    5. 是否是 lock 子节点中序号最小的,如果是则获取到了锁;
    6. 如果不是,则重复以上步骤,继续获取到比自己小的一个节点,并注册监听。
      在这里插入图片描述

    Curator 实现分布式锁 API

    在 Curator 中有五种锁方案
    InterProcessSemaphoreMutex:分布式排它锁(非可重入锁)
    InterProcessMutex:分布式可重入排它锁
    InterProcessReadWriteLock:分布式读写锁
    InterProcessMultiLock:将多个锁作为单个实体管理的容器
    InterProcessSemaphoreV2:共享信号量

    package com.itheima.curator;
    
    import org.apache.curator.RetryPolicy;
    import org.apache.curator.framework.CuratorFramework;
    import org.apache.curator.framework.CuratorFrameworkFactory;
    import org.apache.curator.framework.recipes.locks.InterProcessMutex;
    import org.apache.curator.retry.ExponentialBackoffRetry;
    
    import java.util.concurrent.TimeUnit;
    
    //以线程的方式模拟卖票
    public class Ticket12306 implements Runnable{
        private int tickets = 10;//数据库的票数
    
        private InterProcessMutex lock ;
    
        public Ticket12306(){
            RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
    
            CuratorFramework client = CuratorFrameworkFactory.builder()
                    .connectString("192.168.2.212:2181")
                    .sessionTimeoutMs(60 * 1000)
                    .connectionTimeoutMs(15 * 1000)
                    .retryPolicy(retryPolicy)
                    .build();
    
            //开启连接
            client.start();
    
            lock = new InterProcessMutex(client,"/lock");
        }
    
        @Override
        public void run() {
            while(true){
                //获取锁
                try {
                    lock.acquire(3, TimeUnit.SECONDS);
                    if(tickets > 0){
                        System.out.println(Thread.currentThread()+":"+tickets);
                        Thread.sleep(100);
                        tickets--;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }finally {
                    //释放锁
                    try {
                        lock.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    package com.itheima.curator;
    
    public class LockTest {
        public static void main(String[] args) {
            Ticket12306 ticket12306 = new Ticket12306();
    
            //创建客户端
            Thread t1 = new Thread(ticket12306,"携程");
            Thread t2 = new Thread(ticket12306,"飞猪");
    
            t1.start();
            t2.start();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    代码很简单,可靠性都是zookeeper内部帮你做好的。直接 lock = new InterProcessMutex(client,“/lock”);创建锁对象就行

  • 相关阅读:
    Promise从入门到精通(第3章 自定义(手写)Promise)
    电力调度自动化系统,如何减少配电安全隐患?
    Web3:Fediverse低效是一种平衡 - berk
    (最优化理论与方法)第三章优化建模-第二节:回归分析
    wsl Ubuntu 重置后报错
    线程池(重点)
    神经网络模型量化基础
    顶刊BMJ杂志推荐方法学文章!断点回归方法介绍
    学校食堂厨师帽厨师服佩戴识别系统
    主播三维能力总览
  • 原文地址:https://blog.csdn.net/m0_57084845/article/details/134485031