zk使用通知移除节点
前面:https://www.cnblogs.com/toov5/p/9899238.html 服务发生宕机 咋办?
发个事件通知,告知大家哟,
会有通知事件哦
看项目:
服务端:
package com.toov5.zkDubbo; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; import org.I0Itec.zkclient.ZkClient; //##ServerScoekt服务端
public class ZkServerScoekt implements Runnable {
private static int port = 18083; //socket 服务启动后的所使用的 端口号 public static void main(String[] args) throws IOException {
ZkServerScoekt server = new ZkServerScoekt(port); //构造函数传入port
regServer(); //去zk注册
Thread thread = new Thread(server);
thread.start();
} public ZkServerScoekt(int port) {
this.port = port;
}
//注册服务
public static void regServer(){
//1、建立zk连接
ZkClient zkClient = new ZkClient("192.168.91.5",5000,10000);
//2.先创建父节点
String root = "/toov5";
if (!zkClient.exists(root)) {
//如果父节点不存,直接创建父节点
zkClient.createPersistent(root); //持久节点
}
//3、创建子节点
String nodeName = root+"/service_"+port;
String nodeValue="127.0.0.1:"+port;
if (zkClient.exists(nodeName)) { //如果存在 直接删除掉
zkClient.delete(nodeName);
}
zkClient.createEphemeral(nodeName,nodeValue); //字节的 临时节点 如果服务宕机了 找不到了
System.out.println("服务注册成功"+nodeName); } public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println("Server start port:" + port);
Socket socket = null;
while (true) {
socket = serverSocket.accept();
new Thread(new ServerHandler(socket)).start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
} catch (Exception e2) { }
}
} }
客户端
package com.toov5.zkDubbo; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List; import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient; public class ZkServerClient {
public static List<String> listServer = new ArrayList<String>(); public static void main(String[] args) {
initServer();
ZkServerClient client= new ZkServerClient();
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String name;
try {
name = console.readLine();
if ("exit".equals(name)) {
System.exit(0);
}
client.send(name);
} catch (IOException e) {
e.printStackTrace();
}
}
} // 注册所有server
public static void initServer() {
listServer.clear();
// listServer.add("127.0.0.1:18080"); //连接服务 放到list中 存放集群地址 做负载均衡用的
//建立zk连接
final ZkClient zkClient = new ZkClient("192.168.91.5",5000,10000);
//读取父节点信息
final String root = "/toov5";
List<String> children=zkClient.getChildren(root);
for(String pString : children){
//父+子 =完整的路径
String path = root+"/"+pString;
String nodeValue =zkClient.readData(path);
//把值放到集合中去
listServer.add(nodeValue);
}
//服务发现成功
System.out.println("服务发现:"+listServer.toString());
//然后给 serverCount赋值
serverCount=listServer.size(); //使用zk事件监听,如果服务发生宕机情况,重新读取新的节点
zkClient.subscribeChildChanges(root, new IZkChildListener() { public void handleChildChange(String arg0, List<String> children) throws Exception { //children移除之后 剩下的
System.out.println("有服务宕机了,重新读取新的节点信息"+listServer.toString());
listServer.clear(); //清除之前的 然后读取最新的
for(String pString : children){
//父+子 =完整的路径
String path = root+"/"+pString;
String nodeValue =zkClient.readData(path);
//把值放到集合中去
listServer.add(nodeValue);
}
serverCount=children.size();
System.out.println("服务发现"+listServer.toString());
}
}); } //请求总数
private static int reqCount = 1;
//服务个数
private static int serverCount = 0; //初始值是0 // 获取当前server信息
public static String getServer() {
// return listServer.get(0); 不能写死 本地负载均衡轮询算法
String serverName = listServer.get(reqCount%serverCount );
System.out.println("客户端请求次数:"+reqCount+"对应服务器"+serverName);
reqCount++;
return serverName;
} public void send(String name) { String server = ZkServerClient.getServer();
String[] cfg = server.split(":"); Socket socket = null;
BufferedReader in = null;
PrintWriter out = null;
try {
socket = new Socket(cfg[0], Integer.parseInt(cfg[1]));
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true); out.println(name);
while (true) {
String resp = in.readLine();
if (resp == null)
break;
else if (resp.length() > 0) {
System.out.println("Receive : " + resp);
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>zkDobbo</groupId>
<artifactId>com.toov5.zkDubbo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.8</version>
</dependency>
</dependencies>
</project>
启动三个服务端,一个客户端。然后随机关闭一个服务端:
控制台:
当有新节点启动时候:
核心部分代码欣赏~~
zk使用通知移除节点的更多相关文章
- dom4j移除节点不成功
在使用dom4j的时候想移除xml节点,经常使用remove来移除节点,通过整个文档或者根节点删除某一个子节点,但如果子节点不是儿子节点,在dom4j中就无法删除.在dom4j中移除节点必须使用父节点 ...
- 使用 kubectl drain 从集群中移除节点
对节点执行维护操作之前(例如:内核升级,硬件维护等),您可以使用 kubectl drain 安全驱逐节点上面所有的 pod.安全驱逐的方式将会允许 pod 里面的容器遵循指定的 PodDisrupt ...
- Hadoop中正确地添加和移除节点
正确地添加和移除节点 添加节点 克隆 克隆一台全新的Linux(如有IP冲突,可右击VMware右下角网络图标断开连接) 打开/etc/hostname修改主机名 打开/etc/sysconfig/n ...
- etcd集群移除节点
查看当前集群信息 # etcdctl member list --write-out=table +------------------+---------+--------------------+ ...
- JS递归及二叉搜索树的移除节点
1递归含义:在某时某刻某个条件下调用包含自己的函数 2:注意点:⑴递归过程中一定要加限制条件,要不然会陷入死循环: 死循环eg: function f(someP){ f(somP); } f(4); ...
- k8s节点简介、移除节点、新增节点
简介 Node是Pod真正运行的主机,可以是物理机也可以是虚拟机. Node本质上不是Kubernetes来创建的, Kubernetes只是管理Node上的资源. 为了管理Pod,每个Node节点上 ...
- k8s系列--node(k8s节点介绍,新增节点,移除节点)
一.简介 Node是Pod真正运行的主机,可以是物理机也可以是虚拟机. Node本质上不是Kubernetes来创建的, Kubernetes只是管理Node上的资源. 为了管理Pod,每个Node节 ...
- JDK8 HashMap--removeNode()移除节点方法
/*删除节点*/ final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, bo ...
- hadoop移除节点的优雅方式
step 1:使用hdfs-site.xml的配置项,排除节点. <property> <name>dfs.hosts.exclude</name> <val ...
随机推荐
- Oracle服务扫描工具Oscanner
Oracle服务扫描工具Oscanner Oracle是甲骨文公司推出的关系型数据库,适用于中大规模数据存储,如大型企业.电信.银行等行业.Kali Linux集成了Oracle服务扫描专向工具O ...
- 简单的makefile模板
makefile不是总用到,每次用到的时候总要重新找资料,有点麻烦(怪自己基础知识不扎实,汗).留一个通用模板放这,方便以后使用 CC = gcc CXX = g++ LINK = g++ CFLAG ...
- 1004 Counting Leaves
A family hierarchy is usually presented by a pedigree tree. Your job is to count those family member ...
- Java中判断String对象是否为空的方法
Java原生的方法: String对象中有一个isEmpty的方法判断是否为空,其实isEmpty完全等同于string.length()==0,注意如果String本身是null,那么使用strin ...
- Java中ArrayList的初始容量和容量分配
1.实例化ArrayList时默认不输入大小是10个,并且如果增加到11个时不会报错,会自动扩容. 2.获取指定索引的值时就必须保证ArrayList有这么多个. 3.推荐在new ArrayList ...
- BT种子文件文件结构分析(转)
估计80%以上接触互联网的人都知道bt是什么东西,任何一个用bt下载的人都知道这样一个概念,种子.bt种子就是记录了p2p对等网络中tracker, nodes, files等信息,也就是说,这个种子 ...
- 结构体和类中属性定义需要static地方
private function Readxxx:Integer;static; public class property XXX:Integer read ReadXXx; Txxx =recor ...
- mac apache配置虚拟主机
设置虚拟主机 在终端运行“sudo vi /etc/apache2/httpd.conf”,打开Apche的配置文件 在httpd.conf中找到“#Include /private/etc/apac ...
- linux下命令行的查找顺序
由下可知,linux通过$PATH的路径顺序,由左至由依次查找某个程序,如果有两个路径下都有这个程序,以先找到的为准 [rpc_server]$ which 23/usr/bin/which: no ...
- oralce中相关的概念整理
[数据库名] 概念:就是一个数据库的标识,作用等同于我们的身份证的作用,假设一台机器上安装了多个数据库,那么每一个数据库都会有一个数据库名称相应,这些数据库名称在数据库被创建的时候,数据库名称也会被 ...