分布式助手Zookeeper(七)

2024-05-15 04:38
文章标签 分布式 zookeeper 助手

本文主要是介绍分布式助手Zookeeper(七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

[b][color=olive][size=large]上篇文章,散仙介绍了,分布式环境下,基于zookeeper实现的公平的锁,这篇,我们来看下,如何使用zookeeper来完成非公平锁的模拟,在这之前,我们先来,了解下公平锁和非公平锁的区别。

JAVA JDK提供了公平锁,与非公平锁,但这种实现是基于同一个JVM来说的,
如果同一台机器上,不同的JVM,则可以使用文件锁,来实现,但是这些并不是分布式的模式,虽然可以通过RMI的方式来实现,
但比较繁琐。在分布式的场景里,我们可以轻松的使用zookeeper来实现公平锁与非公平锁

基于zookeeper实现的公平锁与非公平锁的区别

先来通俗的看下二者的区别

公平锁,即先来者先得,只有一个厕所的卫生间,想进去只能是按排队顺序来的,比较公平,first挂掉或释放后,会由secend得到锁,依次类推。

非公平锁,比较暴力,只有一个厕所的卫生间,不用排队,外面围了一堆人等着上厕所,当里面的人出来时,外面的人谁强势,而且力气大,谁就能进去,
极端情况下,如果两个人一样力气大,这时候就该厕所门发挥作用了,一次只能挤进去一个人,反映到我们的程序中,这时候就需要代码同步了,保证
任何时候,只有一个人可以拿到锁。

二者的相同点,都保证了,任何情况下,都只能一个人得到某种资源。但实现的方式不同。
[/size][/color][/b]
[b][color=green][size=large]
实现简述:分布式非公平锁的创建,除了得到锁外,其他的多个监听器,监听同一个锁的情况

实现的流程步骤如下:
[table]
|序号|介绍
|1|创建一个持久znode
|2|多个程序并发的去zk服务上,创建同一个短暂无时序性的节点路径,当一个程序,得到锁时,其他程序,只能监听,不能再次创建,创建时需要同步策略
|3|同一时刻只能有一个创建成功者,能得到锁
|4|没成功者,统一监视得到锁的节点
|5|如果中间得到锁的节点,释放了,或者出意外挂掉了,则重复步骤1,2,3,4
[/table]
拓扑图如下:
[/size][/color][/b]
[img]http://dl2.iteye.com/upload/attachment/0094/6184/d1c73404-ca54-3431-bb0c-2f098577ee03.jpg[/img]
[b][color=olive][size=large]代码如下:[/size][/color][/b]
/***
* @author qin dong liang
*
* */
public class LockUnFair3 implements Watcher {


/**
* ZK实例
* */
private ZooKeeper zk;

/**原子计数锁,防止在zk没有连上前,执行CURD操作*/
private CountDownLatch down=new CountDownLatch(1);

public LockUnFair3() {
// TODO Auto-generated constructor stub
}



public LockUnFair3(String host)throws Exception {
this.zk=new ZooKeeper(host, 5000 , new Watcher() {

@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
/**链接上zk服务,岂可取消阻塞计数**/
if(event.getState()==KeeperState.SyncConnected){
down.countDown();
}

}
});
}
/**
* 字符编码
*
* **/
private static final Charset CHARSET=StandardCharsets.UTF_8;

@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub

if(event.getType()==Event.EventType.NodeDeleted){

//如果发现,监听的节点,挂掉了,那么就重新,进行监听
try{
// System.out.println("注意有锁退出或释放,公平锁开始抢占........");
System.out.println("3我可以去抢占了");
createTemp();
// check();
}catch(Exception e){
e.printStackTrace();

}
}
}

SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


/**
* 关闭zk连接
*
* **/
public void close()throws Exception{
zk.close();
}

Random random=new Random();
/***
* 创建锁node,注意是抢占 的
*
*
* */
public void createTemp()throws Exception{


Thread.sleep(random.nextInt(2500));//加个线程休眠,实现模拟同步功能

if(zk.exists("/a/b", this) != null){
System.out.println("锁被占用,监听进行中......");
}else{



String data=zk.create("/a/b", "a".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("Lock3创建锁成功,节点路径: "+data);

}

// System.out.println("2"+data);

}

public static void main(String[] args)throws Exception {

//Slave s=new Slave("192.168.120.128:2181");
LockUnFair3 lock=new LockUnFair3("192.168.120.128:2181");
// lock.createPersist();//创建主节点
lock.createTemp();
// lock.check();
Thread.sleep(Long.MAX_VALUE);
lock.close();

}



}


[b][color=green][size=large]以上是实现的代码,需要注意的是,在最后抢占锁时,可能会一下多个节点同时去建立名字一样的节点,由于zookeeper的特点,只能由一个建立成功,其他的会抛出异常,为了避免这种情况,散仙,目前的想到的是,在创建一个节点时,通过线程随机休眠,来达到一个同步情况,但这扔有极端情况,虽然几率很小,就是分布式环境下可能有多个节点随机休眠的时间是一样的,所以第二种做法,可以在zk节点维持一个有序的分布式队列,每次只能第一个得到锁,其他的继续等待,下一次的抢占,如此一来,就能保证任何时刻只有一个节点得到锁。

[/size][/color][/b]
[b][color=olive][size=large]
如有什么不足之处,欢迎指正! ^_^
[/size][/color][/b]

这篇关于分布式助手Zookeeper(七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/990831

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

zookeeper端口说明及介绍

《zookeeper端口说明及介绍》:本文主要介绍zookeeper端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、zookeeper有三个端口(可以修改)aVNMqvZ二、3个端口的作用三、部署时注意总China编程结一、zookeeper有三个端口(可以

Jenkins分布式集群配置方式

《Jenkins分布式集群配置方式》:本文主要介绍Jenkins分布式集群配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装jenkins2.配置集群总结Jenkins是一个开源项目,它提供了一个容易使用的持续集成系统,并且提供了大量的plugin满

SpringBoot读取ZooKeeper(ZK)属性的方法实现

《SpringBoot读取ZooKeeper(ZK)属性的方法实现》本文主要介绍了SpringBoot读取ZooKeeper(ZK)属性的方法实现,强调使用@ConfigurationProperti... 目录1. 在配置文件中定义 ZK 属性application.propertiesapplicati

基于Python实现智能天气提醒助手

《基于Python实现智能天气提醒助手》这篇文章主要来和大家分享一个实用的Python天气提醒助手开发方案,这个工具可以方便地集成到青龙面板或其他调度框架中使用,有需要的小伙伴可以参考一下... 目录项目概述核心功能技术实现1. 天气API集成2. AI建议生成3. 消息推送环境配置使用方法完整代码项目特点

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

《Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)》本文主要介绍了Golang分布式锁实现,采用Redis+Lua脚本确保原子性,持可重入和自动续期,用于防止超卖及重复下单,具有一定... 目录1 概念应用场景分布式锁必备特性2 思路分析宕机与过期防止误删keyLua保证原子性可重入锁自动

基于MongoDB实现文件的分布式存储

《基于MongoDB实现文件的分布式存储》分布式文件存储的方案有很多,今天分享一个基于mongodb数据库来实现文件的存储,mongodb支持分布式部署,以此来实现文件的分布式存储,需要的朋友可以参考... 目录一、引言二、GridFS 原理剖析三、Spring Boot 集成 GridFS3.1 添加依赖

Redis实现分布式锁全解析之从原理到实践过程

《Redis实现分布式锁全解析之从原理到实践过程》:本文主要介绍Redis实现分布式锁全解析之从原理到实践过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、背景介绍二、解决方案(一)使用 SETNX 命令(二)设置锁的过期时间(三)解决锁的误删问题(四)Re

Gradle下如何搭建SpringCloud分布式环境

《Gradle下如何搭建SpringCloud分布式环境》:本文主要介绍Gradle下如何搭建SpringCloud分布式环境问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Gradle下搭建SpringCloud分布式环境1.idea配置好gradle2.创建一个空的gr

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式