zookeeper锁原理(如何实现分布式锁)

zookeeper分布式锁的使用会涉及到分布式事物因此封装有@Transactional的方法如下:@OverridepublicBizReturn<String>insertMagicCubeVehicles(MagicCubeVehicleSaveRequestrequest)throwsBizException{ZooKeeperSes…

大家好,又见面了,我是你们的朋友全栈君。

zookeeper分布式锁的使用会涉及到分布式事物
因此封装有@Transactional的方法如下:

@Override
    public BizReturn<String> insertMagicCubeVehicles(MagicCubeVehicleSaveRequest request) throws BizException { 
   
        ZooKeeperSession zkSession = ZooKeeperSession.getInstance();
        zkSession.acquireDistributedLock("/magicCube-lock-"+request.getVehicleNumber());
        try{ 
   
            BizReturn<String> bizReturn = insertMagicCubeVehicle(request);
            return bizReturn;
        }finally { 
   
            // 释放分布式锁
            zkSession.releaseDistributedLock("/magicCube-lock-"+request.getVehicleNumber());
        }
    }

封装的方法:

insertMagicCubeVehicle(request);

在这里插入图片描述
ZooKeeperSession的工具类:

package tf56.magiccube.util.zookeeper;

import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

/** * ZooKeeperSession * @author Administrator * */
public class ZooKeeperSession { 
   

    private static CountDownLatch connectedSemaphore = new CountDownLatch(1);

    private ZooKeeper zookeeper;

    public ZooKeeperSession() { 
   
        // 去连接zookeeper server,创建会话的时候,是异步去进行的
        // 所以要给一个监听器,说告诉我们什么时候才是真正完成了跟zk server的连接
        try { 
   
            this.zookeeper = new ZooKeeper(
                    "mt-zookeeper-vip:2181",
                    50000,
                    new ZooKeeperWatcher());
            // 给一个状态CONNECTING,连接中
            System.out.println(zookeeper.getState());

            try { 
   
                // CountDownLatch
                // java多线程并发同步的一个工具类
                // 会传递进去一些数字,比如说1,2 ,3 都可以
                // 然后await(),如果数字不是0,那么久卡住,等待

                // 其他的线程可以调用coutnDown(),减1
                // 如果数字减到0,那么之前所有在await的线程,都会逃出阻塞的状态
                // 继续向下运行

                connectedSemaphore.await();
            } catch(InterruptedException e) { 
   
                e.printStackTrace();
            }

            System.out.println("ZooKeeper session established......");
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
    }

    /** * 获取分布式锁 * @param productId */
    public void acquireDistributedLock(Long productId) { 
   
        String path = "/product-lock-" + productId;

        try { 
   
            zookeeper.create(path, "".getBytes(),
                    Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            System.out.println("success to acquire lock for product[id=" + productId + "]");
        } catch (Exception e) { 
   
            // 如果那个车辆对应的锁的node,已经存在了,就是已经被别人加锁了,那么就这里就会报错
            // NodeExistsException
            int count = 0;
            while(true) { 
   
                try { 
   
                    Thread.sleep(1000);
                    zookeeper.create(path, "".getBytes(),
                            Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
                } catch (Exception e2) { 
   
                    count++;
                    System.out.println("the " + count + " times try to acquire lock for product[id=" + productId + "]......");
                    continue;
                }
                System.out.println("success to acquire lock for product[id=" + productId + "] after " + count + " times try......");
                break;
            }
        }
    }

    /** * 获取分布式锁 * @param path */
    public void acquireDistributedLock(String path) { 
   
        try { 
   
            zookeeper.create(path, "".getBytes(),
                    Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            System.out.println("success to acquire lock for " + path);
        } catch (Exception e) { 
   
            // 如果那个车辆对应的锁的node,已经存在了,就是已经被别人加锁了,那么就这里就会报错
            // NodeExistsException
            int count = 0;
            while(true) { 
   
                try { 
   
                    Thread.sleep(1000);
                    zookeeper.create(path, "".getBytes(),
                            Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
                } catch (Exception e2) { 
   
                    count++;
                    System.out.println("the " + count + " times try to acquire lock for " + path + "......");
                    continue;
                }
                System.out.println("success to acquire lock for " + path + " after " + count + " times try......");
                break;
            }
        }
    }

    /** * 获取分布式锁 * @param path */
    public boolean acquireFastFailedDistributedLock(String path) { 
   
        try { 
   
            zookeeper.create(path, "".getBytes(),
                    Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
            System.out.println("success to acquire lock for " + path);
            return true;
        } catch (Exception e) { 
   
            System.out.println("fail to acquire lock for " + path);
        }
        return false;
    }

    /** * 释放掉一个分布式锁 * @param productId */
    public void releaseDistributedLock(Long productId) { 
   
        String path = "/product-lock-" + productId;
        try { 
   
            zookeeper.delete(path, -1);
            System.out.println("release the lock for product[id=" + productId + "]......");
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
    }

    /** * 释放掉一个分布式锁 * @param path */
    public void releaseDistributedLock(String path) { 
   
        try { 
   
            zookeeper.delete(path, -1);
            System.out.println("release the lock for " + path + "......");
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
    }

    public String getNodeData(String path) { 
   
        try { 
   
            return new String(zookeeper.getData(path, false, new Stat()));
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
        return "";
    }

    public void setNodeData(String path, String data) { 
   
        try { 
   
            zookeeper.setData(path, data.getBytes(), -1);
        } catch (Exception e) { 
   
            e.printStackTrace();
        }
    }

    public void createNode(String path) { 
   
        try { 
   
            zookeeper.create(path, "".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        } catch (Exception e) { 
   

        }
    }

    /** * 建立zk session的watcher * @author Administrator * */
    private class ZooKeeperWatcher implements Watcher { 
   

        public void process(WatchedEvent event) { 
   
            System.out.println("Receive watched event: " + event.getState());
            if(KeeperState.SyncConnected == event.getState()) { 
   
                connectedSemaphore.countDown();
            }
        }

    }

    /** * 封装单例的静态内部类 * @author Administrator * */
    private static class Singleton { 
   

        private static ZooKeeperSession instance;

        static { 
   
            instance = new ZooKeeperSession();
        }

        public static ZooKeeperSession getInstance() { 
   
            return instance;
        }

    }

    /** * 获取单例 * @return */
    public static ZooKeeperSession getInstance() { 
   
        return Singleton.getInstance();
    }

    /** * 初始化单例的便捷方法 */
    public static void init() { 
   
        getInstance();
    }

}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/129412.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vsftp账号_Vsftp用户限制

    vsftp账号_Vsftp用户限制背景Oracle全库备份,异地备份在实现异地备份后,由第三方人员登录服务器拉取dmp文件.为了确保安全,创建一个特定ftp账号用于第三方人员使用要求1.可以登录服务器2.可以拉取dmp文件3.仅限在dmp文件的目录下,不能cd其他路径,ls其他目录解决过程yum安装ftp服务[root@78778e06dc0a/]#yuminstallvsftpd-y修改vsftp配置文件,开启限制[…

    2025年7月20日
    5
  • 个人网站开发流程(网站开发的工作流程图)

    1.确定主题选择主题应该是小而精,目标定位要小,内容要精。不要去试图制作一个包罗万象的站点,这往往会失去网站的特色,也会带来高强度的劳动,给网站的及时更新带来困难。一定记住,在互联网只有第一,没有第二。2.选择域名在互联网世界中,域名就是网站的名字。一个好记,易记得域名会给个人网站加分,当积累了一定的用户的人气的个人网站,域名的价值就会体现出来。3.学习网页设计和开发技术对于常…

    2022年4月14日
    44
  • WebService简单案例实例

    WebService简单案例实例本周工作日即将结束,下周项目经理安排了一项任务可能需要使用到webservice,但本人之前尚未使用过,网上查了一些案例看了看在此小记一篇留作日后回首也希望可以帮助到查看者朋友1、什么是WebService?WebService是一种远程调用技术,也叫XMLWebServiceWebService,是一种可以接收从Internet或者Internet上的其他系统中传递过来的请求,轻量级的独…

    2022年7月21日
    17
  • Boston 旅游

    Boston 旅游海滩:http://www.hamptonbeach.org/ http://www.newportmansions.org/ http://www.foxwoods.com/http://www.sunshineboston.com/bustours/mohegansun/ LaoShiChun:ConvenientPlaza,502BostonRd.Bille

    2022年6月12日
    33
  • 第七课 实战文件注册机制「建议收藏」

    第七课 实战文件注册机制「建议收藏」                实战文件注册机制【盲人摸象】故名思意就是借助一些我们常用的按钮事件,API断点,去高速有效的锁定此课主要是以回顾和巩固以上六课我们所学的知识,当然这课我奉劝大家还是认真的学习,尤其是以后想靠外挂赚钱的同学,这课学得多自然就会得多不要认为我就是一味的靠我的经验,以下就是一系列调试的技巧 这课主要是观看MOV的赋值,以及寄存器的变化,从而达到激活成功教程这也是以后在激活成功教程带有V…

    2022年7月26日
    5
  • android toast居中显示_android Toast 弹出在屏幕中间位置以及自定义Toast

    android toast居中显示_android Toast 弹出在屏幕中间位置以及自定义ToastToast我想我们应该使用的都很多,一般我们使用默认设置较多,但是默认设置往往不能满足我们的需求,那我们现在来自定义下:默认Toast:Toast.makeText(MainActivity.this,”点击按钮”,Toast.LENGTH_SHORT).show();设置Toast位置:通过setGravity设置Toast位置,可以是Gravity.CENTER:中间Gravity.BOTT…

    2025年11月3日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号