版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xsm666/article/details/85260861
通过curator框架注册节点信息到zookeeper上,在客户端和zookeeper之间的网络连接不稳定的的时候会有掉线的情况,等到网络重新恢复正常的时候并不会重新再向zookeeper中注册节点信息,这个重新注册的操作需要利用curator的监听器来实现。
注册代码:
CuratorFramework curator = CuratorFrameworkFactory.newClient("192.168.0.100:2181",
5000, 3000, new RetryNTimes(5, 1000));
curator.start();
String regContent = "192.168.1.5:2688";
String zkRegPathPrefix = "/codelast/service-provider-";
//TODO:
curator.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath(zkRegPathPrefix, regContent.getBytes("UTF-8"));
如果你是在项目启动的时候实现注册的,那么这端代码只会执行一次,网络掉线后不会冲新注册,这时要实现curator的一个监听器,代码如下:
MyConnectionStateListener stateListener = new MyConnectionStateListener(zkRegPathPrefix, regContent);
curator.getConnectionStateListenable().addListener(stateListener);
MyConnectionStateListener 类的代码:
public class MyConnectionStateListener implements ConnectionStateListener {
private String zkRegPathPrefix;
private String regContent;
public MyConnectionStateListener(String zkRegPathPrefix, String regContent) {
this.zkRegPathPrefix = zkRegPathPrefix;
this.regContent = regContent;
}
@Override
public void stateChanged(CuratorFramework curatorFramework, ConnectionState connectionState) {
if (connectionState == ConnectionState.LOST) {
while (true) {
try {
if (curatorFramework.getZookeeperClient().blockUntilConnectedOrTimedOut()) {
curatorFramework.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath(zkRegPathPrefix, regContent.getBytes("UTF-8"));
break;
}
} catch (InterruptedException e) {
//TODO: log something
break;
} catch (Exception e) {
//TODO: log something
}
}
}
}
}
这样在网络掉线后实现重新注册的代码就写好好了,那么如何测试呢:
测试方法有两种,目的都是模拟网络掉线的情况
①如果是Linux虚拟机,保持客户端连接正常的情况下,将Linux虚拟机挂起后,再开启虚拟机;这样会造成短暂的网络掉线,在开启虚拟机后网络恢复正常,监听器就立马会起作用
②如果不是虚拟机,可使用Linux的网路丢包率命令,将网络延迟,也是模拟网络不稳定的情况;
设置网络丢包率策略:sudo tc qdisc add dev ens33 root netem delay 2000ms(网络延迟两秒)
删除网络丢包率策略:sudo tc qdisc del dev ens33 root netem delay 2000ms
这个做法是先设置丢包率,待发生网络掉线时,删除丢包率策略,即可触发监听器