世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。
- 命名服务,其实就是在zk中设置一个服务节点,该节点保存着该服务的地址,其他服务要调用这个服务时,会从zk中获取这个节点,当监听并获取到该节点及其地址时,就说明该节点已经就绪并已准备好提供服务,其他节点就可以对该节点进行调用了。
- 这种方式其实与编程中的面向接口编程非常相似,该服务的节点就相当于一个接口,在该服务没有实现时,就可以将节点暴露出来,并告诉其他服务的开发者该服务将要提供的功能。其他服务的开发者就可以针对该服务将要提供的功能并行开发,而无需等到该服务完成后再开发。而对接时只要对该服务对应的znode监听即可,只要该服务完成并注册到zk,就会被发现,然后会被系统自动调用。以下是监听/serv服务的url的实现:
public class NameService {
@Test
public void test() throws Exception {
getData();
Thread.sleep(600000);
close();
}
private ZooKeeper zk = getZk();
private ZooKeeper getZk() {
try {
String conn = "127.0.0.1:2181";
int tout = 15000;
return new ZooKeeper(conn, tout, null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void close() {
try {
if (null != zk) {
zk.close();
}
} catch (Exception e) { e.printStackTrace(); }
}
private void getData() {
String path = "/serv";
AsyncCallback.DataCallback callback = getCallBack();
String ctx = "ctx";
Watcher watcher = getWatcher();
zk.getData(path, watcher, callback, ctx);
}
private Watcher getWatcher() {
return (event) -> {
Watcher.Event.EventType type = event.getType();
String path = event.getPath();
print("type : " + type);
print("path : " + path);
getData();
};
}
private AsyncCallback.DataCallback getCallBack() {
return (rc, path, ctx, bytes, stat) -> {
KeeperException.Code code = KeeperException.Code.get(rc);
String url = null;
if (KeeperException.Code.OK.equals(code) && null != bytes) {
url = new String(bytes);
}
print("code : " + code);
print("url : " + url);
};
}
private void print(Object obj) {
System.out.println(obj);
}
}
这里使用原生的ZooKeeper类并通过通过异步的方式实现调用,希望对大家有所帮助。