Zookeeper它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
简单来说zookeeper=文件系统+监听通知机制.
它相对于用Redis来做服务注册,优点就是能通知。
我们以前做游戏服务的时候,也有一个中心服,就是干这个的。就是好多服务可以注册上来,然后,它可以对注册了监听的服务,进行通知这个变化。
Zookeeper除了注册服务外,还可以管比如理配置文件这样的大小不大的小文件。
当安装好Zookeeper后,可以用它自带的客户端,进行各种操作。我们的服务,对接这个用的是JAVA的客户端,遇到一些需要注意的地方。如下:
1. 直接写IP:PORT给它做参数的话,遇到了连接非常慢的问题,大概卡住十几秒,是由DNS解析造成的。所以,需要修改host文件,给这个IP配一个简单的域名,初始化的参数,变成HOST:PORT的形式。速度就很快了。
2. 通知是一次性的。当通知回调回来之后,需要重新注册。能监听变化的,比如用zk.exist(path,true)。创建ZK实例的时候,传递的wacher在数据变化的时候,会收到事件通知。
3. ZK客户端内部在disconnected之后,会自动重连ZK服务。需要我们重连的是在收到Expired事件之后,如果收到了这个,代表ZK服务挂了。我们需要重新初始化ZK客户端,进行连接, 然后走一遍注册的流程。
package com.qp;
import org.apache.zookeeper.*;
public class ZKHelper implements Watcher {
private ZooKeeper zooKeeper = null;
@Override
public void process(WatchedEvent event) {
System.out.println("[ZKHelper======>] receive the event:"+event);
if(Event.KeeperState.SyncConnected == event.getState()) {
switch (event.getType()){
case NodeCreated:
case NodeDeleted:
case NodeDataChanged:{
try {
zooKeeper.exists("/evnet", true);
}catch (Exception e){
e.printStackTrace();
}
}
}
}else{
if(Event.KeeperState.Expired==event.getState()){
try{
zooKeeper.close();
}catch (Exception e){
e.printStackTrace();
}
setup();
}
}
}
public void setup(){
ZKHelper helper = new ZKHelper();
try {
zooKeeper = new ZooKeeper("zk01:2181",5000,helper);
while(zooKeeper.getState()!=ZooKeeper.States.CONNECTED);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("zookeeper session established");
/*try {
zooKeeper.setData("/evnet", (System.currentTimeMillis()+"").getBytes(), -1);
}catch (Exception e){
e.printStackTrace();
} */
try {
zooKeeper.exists("/evnet", true);
}catch (Exception e){
e.printStackTrace();
}
}
public void close(){
if(zooKeeper != null) {
try {
zooKeeper.close();
} catch (Exception e) {
e.printStackTrace();
}
zooKeeper = null;
}
}
public static void main(String[] args){
new ZKHelper().setup();
while(true){
try{
Thread.currentThread().sleep(Integer.MAX_VALUE);
}catch (Exception e){
e.printStackTrace();
}
}
}
}