前面: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使用通知移除节点的更多相关文章

  1. dom4j移除节点不成功

    在使用dom4j的时候想移除xml节点,经常使用remove来移除节点,通过整个文档或者根节点删除某一个子节点,但如果子节点不是儿子节点,在dom4j中就无法删除.在dom4j中移除节点必须使用父节点 ...

  2. 使用 kubectl drain 从集群中移除节点

    对节点执行维护操作之前(例如:内核升级,硬件维护等),您可以使用 kubectl drain 安全驱逐节点上面所有的 pod.安全驱逐的方式将会允许 pod 里面的容器遵循指定的 PodDisrupt ...

  3. Hadoop中正确地添加和移除节点

    正确地添加和移除节点 添加节点 克隆 克隆一台全新的Linux(如有IP冲突,可右击VMware右下角网络图标断开连接) 打开/etc/hostname修改主机名 打开/etc/sysconfig/n ...

  4. etcd集群移除节点

    查看当前集群信息 # etcdctl member list --write-out=table +------------------+---------+--------------------+ ...

  5. JS递归及二叉搜索树的移除节点

    1递归含义:在某时某刻某个条件下调用包含自己的函数 2:注意点:⑴递归过程中一定要加限制条件,要不然会陷入死循环: 死循环eg: function f(someP){ f(somP); } f(4); ...

  6. k8s节点简介、移除节点、新增节点

    简介 Node是Pod真正运行的主机,可以是物理机也可以是虚拟机. Node本质上不是Kubernetes来创建的, Kubernetes只是管理Node上的资源. 为了管理Pod,每个Node节点上 ...

  7. k8s系列--node(k8s节点介绍,新增节点,移除节点)

    一.简介 Node是Pod真正运行的主机,可以是物理机也可以是虚拟机. Node本质上不是Kubernetes来创建的, Kubernetes只是管理Node上的资源. 为了管理Pod,每个Node节 ...

  8. JDK8 HashMap--removeNode()移除节点方法

    /*删除节点*/ final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, bo ...

  9. hadoop移除节点的优雅方式

    step 1:使用hdfs-site.xml的配置项,排除节点. <property> <name>dfs.hosts.exclude</name> <val ...

随机推荐

  1. awk理论详解、实战

    答疑解惑: 为什么用awk取IP的时候用$4? ifconfig eth0 | awk -F '[ :]+' 'NR==2{print $4}' IP第二行内容如下: inet addr:10.0.0 ...

  2. Android Studio 常见命令

    android studio 常用命令 Description Mac Linux/Win Lookup IDE commands Cmd+Shift+A Ctrl+Shift+A Open Clas ...

  3. Ubuntu 16.04下使用Wine安装正则表达式工具RegexBuddy 4

    说明: 1.使用的Wine版本是深度出品(Deepin),已经精简了很多没用的配置,使启动能非常快,占用资源小. 2.关于没有.wine文件夹的解决方法:在命令行上运行winecfg: 下载: (链接 ...

  4. 【spring cloud】spring cloud子module的pom文件添加依赖,出现unknown问题【maven】

    spring cloud项目,一般都是父项目中有多个子服务,也就是子module模块. 如下图: 问题描述:在父项目中引用了常用的jar包,例如,引入了spring boot的依赖,那么在子项目中引入 ...

  5. linux删除空行操作:awk、grep、tr、sed

    如下:如何删除空行 shen\nshen\\n sen seh sehe she she 真正删除空行,可以使用vim: 通过命令模式删除空行.vim在命令模式下(在vim里输入英文字符:进入命令模式 ...

  6. paramiko获取远程主机的环境变量

    本文的情况,不同的linux系统版本,表现可能不同. 问题:默认情况下,paramiko在远程主机上执行命令的时候,命令的搜索路径为(/usr/local/bin:/bin:/usr/bin),这样我 ...

  7. 如何在Linux中使用sFTP上传或下载文件与文件夹

    如何在Linux中使用sFTP上传或下载文件与文件夹 sFTP(安全文件传输程序)是一种安全的交互式文件传输程序,其工作方式与 FTP(文件传输协议)类似. 然而,sFTP 比 FTP 更安全;它通过 ...

  8. docker 容器 日志占用空间过大问题处理

    docker 容器 日志占用空间过大问题处理 # 2017 10 09 优化docker 运行产生的日志 path=/var/lib/docker/containers/ cd $path for f ...

  9. Codeforces Round #313 (Div. 2) ABC

    A http://codeforces.com/contest/560/problem/A 推断给出的数能否组成全部自然数. 水题 int a[1010]; bool b[1000010]; int ...

  10. JAVA Timer定时器使用方法

    JAVA  Timer 定时器测试 MyTask.java:package com.timer; import java.text.SimpleDateFormat;import java.util. ...