Zookeeper实现分布式锁

package com.billstudy.zookeeper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

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

/**
 * 注册服务,并且自动监听可用服务列表
 * @author Bill
 * @since V1.0 2015年6月24日 - 上午10:03:24
 */
public class AppServer {

	private ZooKeeper zk = null;

	// 树前缀
	private static final String zkParentPrefix = "/appserver";

	private static final String zkChildPrefix = "/app"; 

	// 维护可用列表
	private final ArrayList<String> availableServerList = new ArrayList<String>();

	public void connectZk(String address){
		try {
			zk = new ZooKeeper("hadoop-server05:2181,hadoop-server06:2181,hadoop-server07:2181", 5000, new Watcher() {
				@Override
				public void process(WatchedEvent event) {

					System.out.println(event.toString());

					if (event.getType() == EventType.NodeChildrenChanged
						&& event.getPath().startsWith(zkParentPrefix)
							) {
						flushServerList();
					}
				}
			});

			// 如果根节点没有,则先创建
			if (zk.exists(zkParentPrefix, true) == null) {
				zk.create(zkParentPrefix, "AppServer root dir ".getBytes("UTF-8"), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
				System.out.println("znode :" + zkParentPrefix + "is not exists , create successful !");
			}

			// 根据当前address创建临时连续子节点,这样多个不同的app child节点不会重复。 zk会自己维护序列
			String childPath = zk.create(zkParentPrefix + zkChildPrefix, address.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

			System.out.println("create " + childPath + " successful, address is :" + address);

			flushServerList();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 收到子节点更新后,刷新当前可用服务列表
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:08:19
	 */
	protected void flushServerList() {
		availableServerList.clear();
		try {
			List<String> children = zk.getChildren(zkParentPrefix, true);
			for (String child : children) {
				byte[] data = zk.getData(zkParentPrefix + "/" + child, true,new Stat());
				availableServerList.add(new String(data,"UTF-8"));
			}
			System.out.println("current available server list:" + availableServerList);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 此处可以用来处理业务逻辑,目前让主线程挂起
	 * @author Bill
	 * @since V1.0 2015年6月24日 - 上午10:24:00
	 */
	public void handle(){
		try {
			// System.out.println("handle ...");
			TimeUnit.HOURS.sleep(Long.MAX_VALUE);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {

		if (args.length != 1) {
			System.err.println("The program first argument must be address !");
			System.exit(1);
		}
		AppServer appServer = new AppServer();
		appServer.connectZk(args[0]);
		appServer.handle();
	}

}

时间: 2024-10-28 16:20:55

Zookeeper实现分布式锁的相关文章

[ZooKeeper.net] 3 ZooKeeper的分布式锁

基于ZooKeeper的分布式锁  源码分享:http://pan.baidu.com/s/1miQCDKk ZooKeeper 里实现分布式锁的基本逻辑: 1.zookeeper中创建一个根节点(Locks),用于后续各个客户端的锁操作. 2.想要获取锁的client都在Locks中创建一个自增序的子节点,每个client得到一个序号,如果自己的序号是最小的则获得锁. 3.如果没有得到锁,就监控排在自己前面的序号节点,并且设置默认时间,等待它的释放. 4.业务操作后释放锁,然后监控自己的节点的

基于zookeeper实现分布式锁

一.分布式锁介绍 分布式锁主要用于在分布式环境中保护跨进程.跨主机.跨网络的共享资源实现互斥访问,以达到保证数据的一致性. 线程锁:大家都不陌生,主要用来给方法.代码块加锁.当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码.当有多个线程访问同一对象的加锁方法/代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段.但是,其余线程是可以访问该对象中的非加锁代码块的. 进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为

基于redis和zookeeper的分布式锁实现方式

先来说说什么是分布式锁,简单来说,分布式锁就是在分布式并发场景中,能够实现多节点的代码同步的一种机制.从实现角度来看,主要有两种方式:基于redis的方式和基于zookeeper的方式,下面分别简单介绍下这两种方式: 一.基于redis的分布式锁实现 1.获取锁 redis是一种key-value形式的NOSQL数据库,常用于作服务器的缓存.从redis v2.6.12开始,set命令开始变成如下格式: SET key value [EX seconds] [PX milliseconds] [

利用Zookeeper实现分布式锁及服务注册中心

原文:利用Zookeeper实现分布式锁及服务注册中心 对于Zookeeper的定义以及原理,网上已经有很多的优秀文章对其进行了详细的介绍,所以本文不再进行这方面的阐述. 本文主要介绍一些基本的准备工作以及zookeeper.net的使用. 本文源代码github地址:https://github.com/Mike-Zrw/ZookeeperHelper zookeeper下载地址:https://archive.apache.org/dist/zookeeper/ ZooInspector下载

zookeeper实现分布式锁优于redis的分布式锁

redis的分布式锁,基于while循环不停的尝试,可以回导致占用cpu,能减缓的方法就是通过sleep一段时间 再去尝试,其实并不ok zookeeper做分布式锁, 是通过在zk上新建一个根node 通过client下面新建临时的node 把这些Node的id的序号设置成有序的,当前client判断这个id是否是最小的,如果是最小的,就执行逻辑,然后断开连接,放掉锁,zk会自动删除这个临时节点,然后这时候发生了变化,会调用client的watcher方法,client判断自己的id是否是最小

Redis实现分布式锁与Zookeeper实现分布式锁区别

Redis实现分布式锁与Zookeeper实现分布式锁区别 **前言: 在学习过程中,简单的整理了一些redis跟zookeeper实现分布式锁的区别,有需要改正跟补充的地方,希望各位大佬及时指出**Redis实现分布式锁思路 基于Redis实现分布式锁(setnx)setnx也可以存入key,如果存入key成功返回1,如果存入的key已经存在了,返回0. Zookeeper实现分布式锁思路 基于Zookeeper实现分布式锁 Zookeeper是一个分布式协调工具,在分布式解决方案中. 多个客

SpringBoot电商项目实战 — Zookeeper的分布式锁实现

上一篇演示了基于Redis的Redisson分布式锁实现,那今天我要再来说说基于Zookeeper的分布式现实. Zookeeper分布式锁实现 要用Zookeeper实现分布式锁,我就不得不说说zookeeper的数据存储.首先zookeeper的核心保存结构是一个DataTree数据结构,其实内部是一个Map<String, DataNode> nodes的数据结构,其中key是path,DataNode才是真正保存数据的核心数据结构,DataNode核心字段包括byte data[]用于

【Zookeeper】分布式锁

一.概述 实现原理 实现代码 一.概述 分布式锁解决方案(目的:为了保证在分布式领域中共享数据安全问题) 数据库实现分布式锁(不推荐.效率特别低) 基于Redis实现分布式锁setNx (非常麻烦考虑死锁.释放问题) .redission分布式锁 基于Zookeeper实现分布式锁(强烈推荐) SpringCloud内置实现全局锁(冷门)实现起来非常简单,使用临时节点释放锁(效率最高).失效时间容易控制 分布式锁(产生的原因:因为服务器产生集群) 在单台服务器上如何生成订号( 保证唯一) UUI

ZooKeeper学习(二)ZooKeeper实现分布式锁

一.简介 在日常开发过程中,大型的项目一般都会采用分布式架构,那么在分布式架构中若需要同时对一个变量进行操作时,可以采用分布式锁来解决变量访问冲突的问题,最典型的案例就是防止库存超卖,当然还有其他很多的控制方式,这篇文章我们讨论一下怎么使用ZooKeeper来实现分布式锁. 二.Curator 前面提到的分布式锁,在ZooKeeper中可以通过Curator来实现. 定义:Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开

基于zookeeper的分布式锁实现 【转】

工作中需要写一个定时任务,由于是集群环境,自然而然想到需要通过分布式锁来保证单台执行..相信大家都会想到使用zk来实现对应的分布式锁.下面就简单介绍一下几种实现 准备工作 有几个帮助类,先把代码放上来 ZKClient 对zk的操作做了一个简单的封装 Java代码 ZKUtil 针对zk路径的一个工具类 Java代码 NetworkUtil 获取本机IP的工具方法 Java代码 --------------------------- 正文开始  -------------------------