curator

version

zookeeper3.5.x可以使用curator4.x及以上的版本,zookeeper3.4.x需要使用更低的curator版本,建议使用zookeeper3.5.x

curator需要的依赖

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>x.x.x</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-nop -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.6</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
</dependencies>

curator使用

创建连接

CuratorFramework client = CuratorFrameworkFactory.builder()
           .connectString("192.168.186.128:2181")
           .sessionTimeoutMs(30000)
           .retryPolicy(new ExponentialBackoffRetry(1000,3))
           .build();
client.start();           

创建节点

client.create()
.creatingParentsIfNeeded()		//如果没有父节点的,则创建父节点
.withMode(CreateMode.PERSISTENT)		//设置创建节点的模式,是永久节点还是临时节点
.forPath("path","data".getBytes();		//创建节点的路径和设置节点的数据,数据只能是byte[]类型

获取数据

Stat stat = new Stat();
byte[] data = client.getDate()
.storingStatIn(stat)		//获取数据的状态
.forPath(paht);

更新数据

client.setDate()
.withVersion(int version)		//如果版本不是最新的版本,则不能更新数据。
.forPath(path);

删除节点

client.delete()
.guaranteed()		//保证zookeeper一定删除该节点
.deletingChildrenIfNeeded()		//如果有子节点,则递归删除子节点
.withVersion(stat.getVersion())		//要删除数据的版本,如果版本过期则不能删除
.forPath(path);

异步接口

public interface BackgroundCallback{
	public void processResult(CuratorFramework client,CurtorEvent event) throws Exception;
}

CurtorEvent event 参数中定义了服务器端向客户端发送的一系列事件参数,其中比较重要的是事件类型和响应码。

  1. 事件类型(CuratorEventType)
    getType()返回的类型有:
类型描述
CREATEFramework#create() 触发
DELETEdelete()
EXISTScheckExists()
GET_DATAgetData()
SET_DATAsetData()
CHILDRENgetChildren()
SYNCsync(String,object)
GET_ACLgetACL()
WATCHED
CLOSING
  1. 响应码(int)
响应码描述
0ok
-4连接断开
-110节点已经存在
-112会话过期

用法
例如

client.create().creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL)
.inBackground(new BackgroundCallBack(){
	@Override
	public void processResult(CuratorFramework client,CuratorEvent event){
	....
	}
})

使用场景

事件监听

curatoe引入了Cache来实现duizookeeper服务器的监听。Cache是对Curator中事件监听的包装,可以看作是本地缓存试图与远程zookeeper视图的一个比对过程。实现了反复注册监听。Cache主要是分为两类:节点监听、子节点监听。

  1. NodeCache
    NodeCache 不仅仅可以监听节点的数据变化,也可以监听该节点是否存在,如果不存在,则在创建该节点时触发NodeCacheListener,但是节点删除时不能触发。

构造方法

public NodeCache(CuratorFramework client,String path);
public NodeCache(CuratorFramwork client,String path,boolean dataIsCompressed)

回调接口

public interface NodeCacheListener{
	public void nodeChanged() throws Exception;
}

使用

fianl NodeCache cache = new NodeCache(client,path,false);	//类型需要时final
cache.start(true);	//当使用true时,在cache第一次启动时hui立即从zookeeper获取数据。
cache.getListenable().addListener(new NodeCacheListener(){
	public void nodeChanged() throws Exception{
		String data = new String(cache.getCurrentData().gatData());
		.....
	}
})
  1. PathChildrenCache
    PathChildrenCache 用于监听zookeeper数据节点的子节点的变化情况。
    构造方法
public PathChildrenCache(CuratorFramework client,String path,boolean cacheData);
public PathChildrenCache(CuratorFramework client,String path,boolean cacheData,ThreadFactory threadFactory);
public PathChildrenCache(CuratorFramework client,String path,boolean cacheData,boolean dataIsCompressed, ThreadFactory threadFactory);
public PathChildrenCache(CuratorFramework client,String path,boolean cacheData,ExecutorService executorService);
public PathChildrenCache(CuratorFramework client,String path,boolean cacheData,boolean dataIsCompressed,ExecutorService executorService);

回调接口

public interface PathChildrenCacheListener{
	public void childEvent(CuratorFramework client,PathChildrenCacheEvent event) throws Exception;
}

在PathChildrenCacheEvent 中定义了所有的事件类型,主要包括:新增节点(CHILD_ADDED)、子节点变更(CHILD_UPDATED)、子节点删除(CHILD_REMOVED)三类
使用

PathChildrenCache cache = new PathChildrenCache(client,path,true);
cache.start()
cache.getListenerable().addListener(new PathChildrenCacheListener(){
	public void childEvent(CuratorFramework client,PathChildrenCacheEvent) throws Exception{
		......
	}
})

Master 选举

对于一个复杂的任务,仅仅需要从集群中选取一台主机进行处理。诸如此类的问题统统称为Master选举。

解决思路
在zookeeper服务器中选取一个节点,多台机器同时向该节点创建一个相同的子节点,由于zookeeper的特性,最终只会有一个机器创建成功,创建成功的这个机器就作为Master。
实现

//master选举的根节点
static String master_path = "/curator_master";
//创建服务器
static CuratorFramework client = new CuratorFrameworkFactory.builder()
	.connectString(host:port)
	.retryPolicy(new ExponentialBackoffRetry(1000,3)).build();
public static void main(String[] args) throws Exception{
	client.start();
	LeaderSelector selector = new LeaderSelectro(client,master_path,new LeaderSelectorListenerAdapter(){
		public void takeLeadership(CuratorFramework client) thrwos Exception{
			......//处理逻辑。
		}
	}
}

在curator 竞争到master以后会调用takeLeadership(curatroFramework client) 方法,在这个方法中实现业务逻辑。当业务逻辑执行完毕以后会立即释放Master权力,然后进行新一轮的Master选举。

分布式锁

解决思路
利用zookeeper的特性,多台机器在同一个节点下创建相同的一个节点。zookeeper保证最终只有一台机器可以创建成功。而创建成功的机器获取到执行权。
实现

//创建锁的根节点。
static String lock_path = "curator_path";
static CuratorFramework client = CuratorFrameworkFactory.builder()
	.connectString(Host:port)
	.retryPolicy(new ExponentialBackoffRetry(1000),3)).build();
	
public static void main(String[] args) throws Exception{
	client.start();
	final InterProcessMutex  lock = new InterProcessMutex(client,lock_path);	//分布式锁。
}

分布式计数器

解决思路
在zookeeper指定的数据节点上通过分布式锁来更新数据。
实现

static String atomic_path= "atomicInteger_path";
static CuratorFramework client = CuratorFrameworkFactory.builder()
	.connectString(Host:port)
	.retryPolicy(new ExponentialBackoffRetry(1000),3)).build();
public static void main(String[] args) throws Exception{
	client.start();
	DistributedAtomicInterger atomicInteger = new DistributedAtomicInteger(client,atomic_path,new RetryNTimes(3,1000));
	AtomicValue<Integer> rc = atomicInteger.add(1);
	rc.succeeded();
}

分布式Barrier

实现1

static String path = "path";

static CuratorFramework client = CuratorFrameworkFactory.builder()
	.connectString(Host:prot)
	.retryPolicy(new ExponentialBackoffRetry(1000,3)).build();
	client.start();
	DistributedBarrier barrier= new DistributedBarrier(client,path);
	//处理逻辑
	barrier.setBarrier();		//设置栅栏,所有的程序运行到这里都回等待。
	barrier.waitOnBarrier(); 		//设置程序等待。

//唤醒等待的程序继续运行
barrier.removeBarrier();

实现2

static CuratorFramework client = CuratorFrameworkFactory.builder()
	.connectString(Host:prot)
	.retryPolicy(new ExponentialBackoffRetry(1000,3)).build();
	client.start();
	//最有以个参数表示要等待多少个线程达到此处才开始继续运行。如果不足则等待。
	DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client,path,5);
	//处理逻辑
	。。。
	barrier.enter();		//当不满足到达的个数时等带,当满足时,自动继续运行。
	//其他处理逻辑
	。。。
	barrier.leaver();		//另外一处等待点,和enter()位置的逻辑相同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值