ZooKeeper是⼀个典型的发布/订阅模式的分布式数据管理与协调框架,我们可以使⽤它来进⾏分布式 数据的发布与订阅。另⼀⽅⾯,通过对ZooKeeper中丰富的数据节点类型进⾏交叉使⽤,配合Watcher 事件通知机制,可以⾮常⽅便地构建⼀系列分布式应⽤中都会涉及的核⼼功能,如数据发布/订阅、命名 服务、集群管理、Master选举、分布式锁和分布式队列等。那接下来就针对这些典型的分布式应⽤场景 来做下介绍。
Zookeeper的两⼤特性:
- 1.客户端如果对Zookeeper的数据节点注册Watcher监听,那么当该数据节点的内容或是其⼦节点 列表发⽣变更时,Zookeeper服务器就会向订阅的客户端发送变更通知。
- 2.对在Zookeeper上创建的临时节点,⼀旦客户端与服务器之间的会话失效,那么临时节点也会被 ⾃动删除
利⽤其两⼤特性,可以实现集群机器存活监控系统,若监控系统在/clusterServers节点上注册⼀个 Watcher监听,那么但凡进⾏动态添加机器的操作,就会在/clusterServers节点下创建⼀个临时节 点:/clusterServers/[Hostname],这样,监控系统就能够实时监测机器的变动情况。
服务器动态上下线监听:
分布式系统中,主节点会有多台,主节点可能因为任何原因出现宕机或者下线,⽽任意⼀台客户端都要 能实时感知到主节点服务器的上下线。
思路分析:
具体实现:
服务端:
// 1 连接ZK
// 2 创建临时顺序节点,数据内容写ip和端口
// 3 创建时间服务线程
import org.I0Itec.zkclient.ZkClient;
//服务端主要提供了client需要的一个时间查询服务,服务端向zk建立临时节点
public class Server {
//获取zkclient
ZkClient zkClient = null;
private void connectZk() {
// 创建zkclient
zkClient = new ZkClient("linux121:2181,linux122:2181");
//创建服务端建立临时节点的目录
if (!zkClient.exists("/servers")) {
zkClient.createPersistent("/servers");
}
}
//告知zk服务器相关信息
private void saveServerInfo(String ip, String port) {
final String sequencePath = zkClient.createEphemeralSequential("/servers/server", ip + ":" + port);
System.out.println("----->>> ,服务器:" + ip + ":" + port + ",向zk保存信息成功,成功上线可以接受client查询");
}
public static void main(String[] args) {
//准备两个服务端启动上线(多线程模拟,一个线程代表一个服务器)
final Server server = new Server();
server.connectZk();
server.saveServerInfo(args[0], args[1]);
//提供时间服务的线程没有启动,创建一个线程类,可以接收socket请求
new TimeService(Integer.parseInt(args[1])).start();
}
}
服务端提供时间查询的线程类:
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
//提供时间查询服务
public class TimeService extends Thread {
private int port = 0;
public TimeService(int port) {
this.port = port;
}
@Override
public void run() {
//通过socket与client进行交流,启动servers