通常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. filesystem type ntfs not configured in kernel

    移动硬盘是NTFS格式的,挂载时候kernel不支持这格式 出现:filesystem type ntfs not configured in kernel 解决:通过sudo yum install ...

  2. .net core创建控制台应用程序和mvc程序

    一.创建控制台应用程序 1.查看支持哪些类型:dotnet new --help 2.创建项目(先定位到需要创建的目录) dotnet new console -o ./myconsole 3.查看目 ...

  3. leetcode刷题——一些算法技巧总结1.0

    运算符优先级,简单记就是:! > 算术运算符 > 关系运算符 > && > || > 赋值运算符 把数字取反,可以作为一种标记 pythonlast = ...

  4. L - Non-Prime Factors (质数筛选+因子分解)

    In many programming competitions, we are asked to find (or count the number of) Prime Factors of an ...

  5. 常用User-Agent大全

    浏览器User-Agent的详细信息 PC端: safari 5.1 – MAC User-Agent:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8 ...

  6. Vue 知识整理—01-基础

    一:Vue是什么? Vue是一个JS框架. Vue.js是一套构建用户界面的渐进式框架. 库和框架的区别: ☞库:提供一些 API 工具函数,体现了封装的思想,需要我们主动调用: ☞框架:提供一套完整 ...

  7. 一个空格引起的错误。 python

    'render_field' tag requires a form field followed by a list of attributes and values in the form att ...

  8. docker 安装elasticSearch7.0.0

    一.执行命令:docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-n ...

  9. C#UDP广域网,局域网通信-原理分析

    一.UDP局域网通信. 这个比较简单,关于局域网中的2台或者更多的计算机之间的UDP通信,网络上一大把,直接复制粘贴就可以使用,原理也非常简单.所以,本文不做详细介绍. 二.UDP广域通信(包括路由器 ...

  10. SSE技术详解:使用 HTTP 做服务端数据推送应用的技术

    SSE ( Server-sent Events )是 WebSocket 的一种轻量代替方案,使用 HTTP 协议. 严格地说,HTTP 协议是没有办法做服务器推送的,但是当服务器向客户端声明接下来 ...