ZooKeeper连接并创建节点以及实现分布式锁操作节点排序输出最小节点Demo
class LockThread implements Runnable {
private DistributedLock lock; public LockThread(int threadId,CountDownLatch latch) throws Exception {
this.lock = new DistributedLock(threadId,latch);
} @Override
public void run() {
//每一个线程对象启动后都应该创建一个临时的节点信息
try {
this.lock.handle();//进行具体的操作处理
} catch (Exception e) {
e.printStackTrace();
}
}
} public class TestDistributedLock { public static void main(String[] args) throws Exception {
CountDownLatch latch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
new Thread(new LockThread(i,latch)).start();;
}
//Thread.sleep(Long.MAX_VALUE);//为了保证可以观察到所有的临时节点信息,保证此处先不进行关闭
latch.await();
System.out.println("************* 所有的线程对象操作完毕 *************");
}
public class DistributedLock {//建立一个描述分布式锁的程序处理类
public static final String CONNECTION_RUL = "192.168.12.121:2181,192.168.12.122:2181"; public static final int SESSION_TIMEOUT = 2000;//设置连接超时时间 public static final String AUTH_INFO = "zkuser:mldnjava";//进行连接的授权信息 public static final String GROUPNODE = "/mldn-lock";//根节点 public static final String SUNBODE = GROUPNODE + "/lockthread-";//子节点 private CountDownLatch latch = null; //本操作的主要目的是为了在取得zookeeper连接之后才能进行后续的处理
private CountDownLatch connectLatch = new CountDownLatch(1); private ZooKeeper zkClient = null; //建立Zookeeper程序控制类 private String selfPath; //保存每次创建的临时节点信息 private String waitPath; //保存下一个要进行处理的节点 private int threadId = 0; /** 进行一些初始化操作使用
*
* @param threadId 随意给定一个编号信息 * @param latch 进行线程同步处理
* @throws Exception */
public DistributedLock(int threadId, CountDownLatch latch) throws Exception {
this.threadId = threadId;//保存每一个线程对象自己的ID信息
this.latch = latch;
this.connectionZookeeper();//进行节点的连接
} public void handle() throws Exception {//具体业务处理
this.createSubNode();//创建临时节点操作
} public void handleSuccess() throws Exception {//表示取得锁之后进行的处理
if (this.zkClient.exists(this.selfPath, false) == null) {
return;//如果当前节点不存在
}
this.handleCallback();//执行具体的业务操作
//如果某一个节点操作完毕了,那么应该立即删除掉该节点,否则获得的最小节点永远都是该节点
this.zkClient.delete(selfPath, -1);
this.releaseZookeeper();//释放连接
this.latch.countDown();//进行减减的操作
} public void handleCallback() throws Exception {//取得分布式锁之后的目的是要进行具体的操作
Thread.sleep(200);//实现一个延迟处理
System.out
.println("****** Thread-" + this.threadId + "获得操作权,进行具体的业务操作");
} public boolean checkMinPath() throws Exception {//进行最小节点的判断
List<String> childen = this.zkClient.getChildren(GROUPNODE, false);//取得所有的节点信息
Collections.sort(childen); //进行所有节点的排序,这样最小的节点就拍到最上面
int index = childen
.indexOf(this.selfPath.substring(GROUPNODE.length() + 1));
switch (index) {
case 0: {
return true; //已经确定好当前的节点为最小节点
}
case -1: {
return false; //该节点可能已经消失了
}
default: {//表示该节点不属于最小节点,那么应该向后继续排查
this.waitPath = GROUPNODE + "/" + childen.get(index - 1);//获得下一个节点
try {
this.zkClient.getData(waitPath, true, new Stat());//取得下一个节点的数据
return false; //本节点不是当前的操作的最小节点
} catch (Exception e) {//如果出现了异常,则表示该节点不存在
if (this.zkClient.exists(waitPath, false) == null) {
return this.checkMinPath();//继续向后检测
} else {
throw e;
}
}
}
}
} public void createSubNode() throws Exception {//每一个线程对象的启动都要求创建一个节点信息
this.zkClient.create(SUNBODE, ("Thread-" + this.threadId).getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("【Thread-" + this.threadId + "、创建新的临时节点】"
+ this.selfPath);
//当节点创建完成之后就需要进行最小节点的检测
if (this.checkMinPath()) {//如果当前的节点为整个项目的最小节点
this.handleSuccess();//进行锁后的具体操作
}
} public void connectionZookeeper() throws Exception {//连接zookeeper服务
this.zkClient = new ZooKeeper(CONNECTION_RUL, SESSION_TIMEOUT,
new Watcher() { @Override
public void process(WatchedEvent event) {
if (event.getType() == EventType.None) {//第一次连接zookeeper的时候会出现none
DistributedLock.this.connectLatch.countDown();//表示已经连接成功
} else { //要处理删除节点操作,并且要确定下一个节点是已经准备出来的节点信息
if (event.getType() == EventType.NodeDeleted
&& event.getPath().equals(
DistributedLock.this.waitPath)) {
try {
if (DistributedLock.this.checkMinPath()) {//如果当前的节点为整个项目的最小节点
DistributedLock.this.handleSuccess();//进行锁后的具体操作
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});
this.zkClient.addAuthInfo("digest", AUTH_INFO.getBytes());//进行授权认证
if (this.zkClient.exists(GROUPNODE, false) == null) {
this.zkClient.create(GROUPNODE, "LOCKDEMO".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
this.connectLatch.await();//等待连接后才执行后续的功能
} public void releaseZookeeper() {//进行zookeeper的连接释放
if (this.zkClient != null) {
try {
this.zkClient.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
ZooKeeper连接并创建节点以及实现分布式锁操作节点排序输出最小节点Demo的更多相关文章
- zookeeper应用:屏障、队列、分布式锁
zookeeper工具类: 获取连接实例:创建节点:获取子节点:设置节点数据:获取节点数据:访问控制等. package org.windwant.zookeeper; import org.apac ...
- ZooKeeper实践方案:(7) 分布式锁
1.基本介绍 分布式锁是控制分布式系统之间同步訪问共享资源的一种方式,须要相互排斥来防止彼此干扰来保证一致性. 利用Zookeeper的强一致性能够完毕锁服务.Zookeeper的官方文档是列举了两种 ...
- zookeeper 实现分布式锁zookeeper 使用 Curator 示例监听、分布式锁
下载地址: http://download.csdn.net/download/ttyyadd/10239642
- 在非SQL客户端使用命令行方式定期连接SQL Server 服务器并模拟用户查询操作,同时输出信息内容
一个很长的标题,实现的功能就是尽量使用非人力的方式模拟人去做一件事情,为了便于记录,将他们输出成文件方便查阅. 图形界面方式,使用微软自己的ConnMaker.exe,或者Microsoft 数据连接 ...
- 整理分布式锁:业务场景&分布式锁家族&实现原理
1.引入业务场景 业务场景一出现: 因为小T刚接手项目,正在吭哧吭哧对熟悉着代码.部署架构.在看代码过程中发现,下单这块代码可能会出现问题,这可是分布式部署的,如果多个用户同时购买同一个商品,就可能导 ...
- zookeeper分布式锁实现
1.定义分布式锁接口 package com.ljq.lock; import java.util.concurrent.TimeUnit; public interface DistributedL ...
- 分布式锁2 Java非常用技术方案探讨之ZooKeeper
前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.以自己结合实际工作中的一些经验和网上看到的一些资料 ...
- 跟着大神学zookeeper分布式锁实现-----来自Ruthless
前几天分享了@Ruthless大神的Redis锁,发现和大家都学习了很多东西.因为分布式锁里面,最好的实现是zookeeper的分布式锁.所以在这里把实现方式和大家分享一下. zookeeper分布式 ...
- zookeeper分布式锁
摘要:分享牛原创,zookeeper使用,zookeeper锁在实际项目开发中还是很常用的,在这里我们介绍一下zookeeper分布式锁的使用,以及我们如何zookeeper分布式锁的原理.zooke ...
随机推荐
- kubectl自动补全
source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ...
- 展开隐形的翅膀,WPR003N补完篇
在上一回合要搞刷机!从它的尸体上踏过去!钢板云路由!WPR003N复活!成功启动OPENWRT中,笔者成功的让一个4年前主流芯片搭上OS的快船,留下一段佳话. 今天看着抽屉里的WPR003N,回忆它之 ...
- HTML5支持服务器发送事件(Server-Sent Events)-单向消息传递数据推送(C#示例)
传统的WEB应用程序通信时的简单时序图: 现在Web App中,大都有Ajax,是这样子: HTML5有一个Server-Sent Events(SSE)功能,允许服务端推送数据到客户端.(通常叫数据 ...
- AngularJS 截取字符串
参考文章:https://blog.csdn.net/u010234516/article/details/54631525 //过滤器 app.filter('textLengthSet', fun ...
- CSS超出省略号样式
overflow:hidden;text-overflow:ellipsis;-wekit-line-clamp:3;display:-webkit-box;-webkit-box-orient:ve ...
- 数据结构——Java实现单链表
一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...
- iframe中的a标签电话链接不能正常打开
背景 经测试,android手机中没有这个问题, iphone手机中的Safari浏览器会出现这个问题. 例如: <a href = "tel://1-408-555-5555&quo ...
- js实现浏览器调用电脑的摄像头拍照
<!DOCTYPE html> <html lang="en"> <head> <style> * { margin: ; padd ...
- 微信小程序之菜鸟入门教学(二)
昨天学习了一些简单的概念,今天开始实际操作,通过搭建简单的计算器来学习小程序的架构 一.小程序框架 程序框架如上图所示.由此可见,框架的基本构成为: 1. app.js . app.wxss 2. a ...
- ORA-279 signalled during: alter database recover logfile
在RMAN的RECOVER还原过程中,RMAN界面正常,但是检查.刷新告警日志,发现告警日志里面有ORA-279,如下所示: alter database recover logfile '/u06/ ...