通常zookeeper在分布式服务中作为注册中心,实际上它还可以办到很多事。比如分布式队列、分布式锁

由于公司服务中有很多定时任务,而这些定时任务由于一些历史原因暂时不能改造成框架调用

于是想到用zookeeper特性来实现

首先我们先了解下zk工作原理

结构图解释:左侧树状结构为zookeeper集群,右侧为程序服务器。所有的服务器在启动的时候,都会订阅zookeeper中master节点的删除事件,以便在主服务器挂掉的时候进行抢主操作;所有服务器同时会在servers节点下注册一个临时节点(保存自己的基本信息),以便于应用程序读取当前可用的服务器列表。

选主原理介绍:zookeeper的节点有两种类型,持久节点跟临时节点。临时节点有个特性,就是如果注册这个节点的机器失去连接(通常是宕机),那么这个节点会被zookeeper删除。选主过程就是利用这个特性,在服务器启动的时候,去zookeeper特定的一个目录下注册一个临时节点(这个节点作为master,谁注册了这个节点谁就是master),注册的时候,如果发现该节点已经存在,则说明已经有别的服务器注册了(也就是有别的服务器已经抢主成功),那么当前服务器只能放弃抢主,作为从机存在。同时,抢主失败的当前服务器需要订阅该临时节点的删除事件,以便该节点删除时(也就是注册该节点的服务器宕机了或者网络断了之类的)进行再次抢主操作。从机具体需要去哪里注册服务器列表的临时节点,节点保存什么信息,根据具体的业务不同自行约定。选主的过程,其实就是简单的争抢在zookeeper注册临时节点的操作,谁注册了约定的临时节点,谁就是master。

到此我们就可以着手实现了

 public class ZkMasterChooseUtil {

     public static final Map<String,ZkClient > map = new ConcurrentHashMap<>();
public static final Map<String,String > pathMap = new ConcurrentHashMap<>();
public static final Map<String,List<String>> childMap = new ConcurrentHashMap<>(); public static final String IP = getServerIp(); public static final boolean isMaster(String zkServer,String path){ try {
if (!map.containsKey(zkServer)){
reconnect(zkServer);
}
}catch (Exception e){
reconnect(zkServer);
}
String seq = null;
if (!pathMap.containsKey(path)){
if (!map.get(zkServer).exists(path)){
map.get(zkServer).createPersistent(path,true);
}
map.get(zkServer).subscribeChildChanges(path, (parentPath, currentChilds) -> {
childMap.put(parentPath,resetList(currentChilds != null? currentChilds : new ArrayList<>()));
});
pathMap.remove(path);
seq = map.get(zkServer).createEphemeralSequential(path+"/",IP);
pathMap.put(path,seq);
List<String> list = map.get(zkServer).getChildren(path);
childMap.put(path,resetList(list != null ? list : new ArrayList<>()));
}
seq = pathMap.get(path);
List<String> list = childMap.get(path);
if(list.size()>0){
if ((path+"/"+list.get(0)).equals(seq)){
return true;
}
System.out.println("path = "+(path+"/"+list.get(0)) +" seq = "+seq);
}
return false;
} private static void reconnect(String zkServer){
ZkClient zkClient = new ZkClient(new ZkConnection(zkServer,10000),10000);
map.put(zkServer,zkClient);
} private static String getServerIp() {
try {
InetAddress i = getLocalHostLANAddress();
return i != null ? i.getHostAddress() : null;
} catch (Exception e) {
e.printStackTrace();
}
return "";
} public static InetAddress getLocalHostLANAddress() {
try {
InetAddress candidateAddress = null;
// 遍历所有的网络接口
for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
// 在所有的接口下再遍历IP
for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements(); ) {
InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
// 排除loopback类型地址
if (!inetAddr.isLoopbackAddress()) {
if (inetAddr.isSiteLocalAddress()) {
// 如果是site-local地址,就是它了
return inetAddr;
} else if (candidateAddress == null) {
// site-local类型的地址未被发现,先记录候选地址
candidateAddress = inetAddr;
}
}
}
}
if (candidateAddress != null) {
return candidateAddress;
}
// 如果没有发现 non-loopback地址.只能用最次选的方案
InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
return jdkSuppliedAddress;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} private static List<String> resetList(List<String> list){
if (list.size() == 0){
return list;
}
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
Long l1 = Long.valueOf(o1.substring(o1.lastIndexOf("/")+1));
Long l2 = Long.valueOf(o2.substring(o2.lastIndexOf("/")+1));
return l1.compareTo(l2);
}
});
return list;
} }

注:传入path即为要抢注的节点

zookeeper分布式服务中选主的应用的更多相关文章

  1. Hadoop Zookeeper 分布式服务框架

    what is Zookeeper? 1,开源的分布式的,为分布式应用提供协调服务的Apache项目2,提供一个简单原语集合,以便于分布式应用可以在它之上构建更高层次的同步服务3,设计非常易于编程,它 ...

  2. Zookeeper分布式服务协调组件

    1.简介 Zookeeper是一个分布式服务协调组件,是Hadoop.Hbase.Kafka的重要组件,它是一个为分布式应用提供一致性服务的组件.   Zookeeper的目标就是封装好复杂易出错的服 ...

  3. Java学习之Dubbo+ZooKeeper分布式服务Demo

    背景:在之前的一个<Java学习之SpringBoot整合SSM Demo>分享中说到搭建ZooKeeper和Dubbo分布式框架中遇到了一些技术问题没能成功,只分享了其中的一个中间产物, ...

  4. 分布式服务框架Zookeeper

    协议介绍 zookeeper协议分为两种模式 崩溃恢复模式和消息广播模式 崩溃恢复协议是在集群中所选举的leader 宕机或者关闭 等现象出现 follower重新进行选举出新的leader 同时集群 ...

  5. 分布式服务框架 Zookeeper -- 管理分布式环境中的数据

    转自:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/index.html Zookeeper 分布式服务框架是 Apa ...

  6. 分布式服务框架 Zookeeper(转)

    分布式服务框架 Zookeeper -- 管理分布式环境中的数据 Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题 ...

  7. 分布式服务框架 Zookeeper -- 管理分布式环境中的数据(转载)

    本文转载自:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ Zookeeper 分布式服务框架是 Apache Had ...

  8. 分布式服务框架 Zookeeper -- 管理分布式环境中的数据--转载

    原文:http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/ Zookeeper 分布式服务框架是 Apache Hadoop ...

  9. 分布式服务框架 Zookeeper — 管理分布式环境中的数据

    本节本来是要介绍ZooKeeper的实现原理,但是ZooKeeper的原理比较复杂,它涉及到了paxos算法.Zab协议.通信协议等相关知识,理解起来比较抽象所以还需要借助一些应用场景,来帮我们理解. ...

随机推荐

  1. python 绘制点线

    plot(x, y) #默认为蓝色实线 plot(x, y, 'r*') #红色星状标记 plot(x, y, 'go-') #带有圆圈标记的绿线 plot(x, y, 'ks:') #带有正方形标记 ...

  2. git 三步走

    git三步走: git add .        (注:别忘记后面的.,此操作是把Test文件夹下面的文件都添加进来) git commit  -m  "提交信息"  (注:“提交 ...

  3. Python 入门小实例笔记

    实例1:打印用户输入的姓名与手机号码知识点:编码,获取输入,变量,标准输出 #encoding=utf-8 import time #1.提示用户输入信息 name = input ("请输 ...

  4. WSGI协议主要包括server和application两部分:

    WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端:WSGI application接收由server ...

  5. ionic 在windows环境下更换logo和加载图片的问题

    做用自己的电脑做ionic项目时,更换logo和加载图片时,无论使用哪种命令,发现都上传不了,并且报错 最后发现,需要将 icon和splash两个文件改为.ai格式才能上传成功. 这是最终生成后的文 ...

  6. CF 552(div 3) E Two Teams 线段树,模拟链表

    题目链接:http://codeforces.com/contest/1154/problem/E 题意:两个人轮流取最大值与旁边k个数,问最后这所有的数分别被谁给取走了 分析:看这道题一点思路都没有 ...

  7. 处女座与复读机 DP

    题目链接:https://ac.nowcoder.com/acm/contest/327/G 题意:给你两个字符串序列,让你根据第二个序列判断是不是 复读机,复读机会有以下特征 1.       将任 ...

  8. MATLAB常用函数(不定时更新)

    1.pause 一般情况下pause(a)表示程序暂停a秒后继续执行,但有时候也存在这种情况,程序中只有pause:并没有参数a,这样的意思是程序暂停,按任意键程序继续执行.2.uiwait(h,ti ...

  9. C++ 命名管道 与Winform跨进程通信

    以下是.NET命名管道解决方案中几个主要的类. NamedPipeNative:这个类和kernal32.dll联系实现命名管道的通信,其中包含一些常用方法和常量. NamedPipeWrapper ...

  10. mac系统vscode环境配置,以及iTerm2配置Zsh + on-my-zsh shell

    https://segmentfault.com/a/1190000013612471?utm_source=tag-newest https://ohmyz.sh/ 一:安装iTerm2终端 htt ...