1 添加zk依赖
2 拿远程接口
3获取远程连接url地址信息
3.1获取Zk对象
3.2获取物理节点下的所有的子节点
3.21判断zk对象是否为空如果不为空获取物理节点
3.22判断子节点是否发生了变化如果发生了变化则重新获取url地址信息
3.3创建集合存储数据
3.4遍历获取顺时节点中的所有数据
3.41获取顺时节点中的URL地址信息
3.42存储到urls集合中
3.43将最新的url地址集合赋值给全局变量类型为volatile
public class TestZkCustomer {
//创建List集合
private volatile List<String> list = new ArrayList<>();
public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException, KeeperException, InterruptedException {
//创建TestZkCustomer对象
TestZkCustomer tc=new TestZkCustomer();
for(int i=0;i<1000;i++){
try{
//远程消费
ProviderZkService service = (ProviderZkService) tc.getService();
//消费
String s = service.testApp("我是消费者"+i);
System.out.println(s);
Thread.sleep(3000);
}catch (Exception e){
}
}
}
public TestZkCustomer() throws KeeperException, InterruptedException {
readUrl();
}
//获取远程代理对象
public Remote getService() throws RemoteException, NotBoundException, MalformedURLException {
//获取随机数字
int index= ThreadLocalRandom.current().nextInt(list.size());
//获取远程链接的URL地址信息
return Naming.lookup(list.get(index));
}
//获取远程消费的URL地址信息
private void readUrl() throws KeeperException, InterruptedException {
//获取Zk对象
ZooKeeper zk=connectionZk();
//获取URL地址信息
if(zk!=null){
//获取物理节点下的所有的子节点
List<String> childrens = zk.getChildren(Constant.ZK_REGISTER, new Watcher() {
@Override
public void process(WatchedEvent event) {
//判断子节点是否发生了变化,如果发生了变化则重新获取url地址信息
if (event.getType() == Event.EventType.NodeChildrenChanged) {
try {
readUrl();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
//创建集合存储数据
ArrayList<String> urls=new ArrayList<>();
//遍历获取顺时节点中的数据
for(String node:childrens){
//获取顺时节点中的URL地址信息
byte[] data = zk.getData(Constant.ZK_REGISTER + "/" + node, false, null);
//存储到urls集合中
urls.add(new String(data));
}
//将最新的url地址集合赋值给全局变量,类型为volatile
list=urls;
}
}
//实现线程同步
private CountDownLatch latch=new CountDownLatch(1);
//获取zk对象
public ZooKeeper connectionZk(){
ZooKeeper zk=null;
try{
zk=new ZooKeeper(Constant.ZK_HOST, Constant.ZK_TIME_OUT, new Watcher(){
@Override
public void process(WatchedEvent event) {
// 判断是否和zk集群链接成功
if(event.getState()==Event.KeeperState.SyncConnected){
latch.countDown(); //唤醒休眠的线程
}
}
});
//让主线程休眠
latch.await();
}catch(Exception ex){
ex.printStackTrace();
}
return zk;
}
}