非公平选举算法
1)首先通过zk创建一个 /server 的PERSISTENT节点
2)多台机器同时创建 /server/leader EPHEMERAL子节点
3)子节点只能创建一个,后创建的会失败。创建成功的节点被选为leader节点
4)所有机器监听 /server/leader 的变化,一旦节点被删除,就重新进行选举,抢占式地创建 /server/leader节点,谁创建成功谁就是leader。

public static void main(String[] args) throws Exception {
zk = new ZooKeeper("127.0.0.1:2181", FairSelectDemo.SESSION_TIMEOUT, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType() + "---" + event.getPath() + "---" + event.getState());
}
});
//zk启动后试着进行选举
selection(); TimeUnit.HOURS.sleep(); //阻塞住
zk.close();
} private static void selection() throws Exception {
try {
//1、创建/server(这个通过zkCli创建好了),参数3表示公有节点,谁都可以改
zk.create("/server/leader", "node1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
//2、没有抛异常,表示创建节点成功了
System.out.println("选举成功");
} catch (KeeperException.NodeExistsException e) {
System.out.println("选举失败");
} finally {
//3、监听节点删除事件,如果删除了,重新进行选举
zk.getData("/server/leader", new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType() + "---" + event.getPath() + "---" + event.getState());
try {
if (Objects.equals(event.getType(), Event.EventType.NodeDeleted)) {
selection();
}
} catch (Exception e) {
}
}
}, null);
}
}

公平选举算法
1)首先通过zk创建一个 /server 的PERSISTENT节点
2)多台机器同时创建 /server/leader EPHEMERAL_SEQUENTIAL子节点
3)/server/leader000000xxx 后面数字最小的那个节点被选为leader节点
4)所有机器监听 前一个 /server/leader 的变化,比如 (leader00001监听 leader00002) 一旦节点被删除,就获取/server下所有leader,如果自己的数字最小那么自己就被选为leader

public static void main(String[] args) throws Exception {
zk = new ZooKeeper("127.0.0.1:2181", UnFairSelectDemo.SESSION_TIMEOUT, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType() + "---" + event.getPath() + "---" + event.getState());
}
}); String leaderPath = "/server/leader"; //1、创建/server(这个通过zkCli创建好了),注意这里是EPHEMERAL_SEQUENTIAL的
//2、和非公平模式不一样,只需要创建一次节点就可以了
nodeVal = zk.create(leaderPath, "node1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); //System.out.println(nodeVal); //启动后试着进行选举
selection(); TimeUnit.HOURS.sleep(); //阻塞住
zk.close();
} private static void selection() throws Exception {
//2、遍历/server下的子节点,看看自己的序号是不是最小的
List<String> children = zk.getChildren("/server", null);
Collections.sort(children); String formerNode = ""; //前一个节点,用于监听
for (int i = ; i < children.size(); i++) {
String node = children.get(i);
if (nodeVal.equals("/server/" + node)) {
if (i == ) {
//第一个
System.out.println("我被选为leader节点了");
} else {
formerNode = children.get(i - );
}
}
}
if (!"".equals(formerNode)) {
//自己不是第一个,如果是第一个formerNode应该没有值
System.out.println("我竞选失败了");
//3、监听前一个节点的删除事件,如果删除了,重新进行选举
zk.getData("/server/" + formerNode, new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType() + "---" + event.getPath() + "---" + event.getState());
try {
if (Objects.equals(event.getType(), Event.EventType.NodeDeleted)) {
selection();
}
} catch (Exception e) {
}
}
}, null);
}
//System.out.println("children:" + children);
}

但是其实上述的写法不是很严谨,比如公平选举算法,如果中间一个节点挂掉了,假设有01,02,03,04节点 比如02挂掉了,03一直监听着02,那么这个时候03应该改为监听01,否则,当01挂了,没有任何节点能被选为leader。 除此之外,各种异常状态都需要我们自己处理。

原文:https://blog.csdn.net/haizeihdj/article/details/80796227

zk实现服务选举的更多相关文章

  1. 基于Lease分布式系统重试服务选举

    /** * Copyright (c) 2015, www.cubbery.com. All rights reserved. */ package com.cubbery.event.retry; ...

  2. dubbo zk 分布式服务项目搭建与配置

    1. 项目 jar  -----提供接口 2. 项目 jar  -----接口实现   provider启动zk main方法启动 start applicationContext.xml <b ...

  3. springboot 注册服务注册中心(zk)的两种方式

    在使用springboot进行开发的过程中,我们经常需要处理这样的场景:在服务启动的时候,需要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,可以故障摘除和负载均衡. 我遇到过两种注 ...

  4. zookeeper篇-zk的选举机制

    点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人. 文章不定期同步公众号,还有各种一线大厂面试原题.我的学习系列笔记. 说说zk的选举机制 基础概念 zxid=事务id=一个时间戳,代表当前事 ...

  5. Dubbo+ZK与Eureka注册中心比较

    Eureka可以很好的应对网络故障导致部分节点失去联系的情况,而不会像zk那样因为选举导致整个集群不可用 dubbo + zk 当向注册中心查询服务注册列表时,可以容忍注册中心返回的是几分钟以前的注册 ...

  6. zookeeper分布式锁和服务优化配置

    转自:https://www.jianshu.com/p/02eeaee4357f?utm_campaign=maleskine&utm_content=note&utm_medium ...

  7. Zookeeper实现Master选举(哨兵机制)

    master选举使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从模式, ...

  8. hadoop系列:zookeeper(2)——zookeeper核心原理(选举)

    1.前述 上篇文章<hadoop系列:zookeeper(1)--zookeeper单点和集群安装>(http://blog.csdn.net/yinwenjie/article/deta ...

  9. zookeeper分布式协调服务的使用一

    Zookeeper是一个高性能,分布式的应用协调服务. 提供服务: 1.集群成员的管理(Group Membership) 2.分布式锁(Locking) 3.选主(Leader Election) ...

随机推荐

  1. 「NOIP2017」「LuoguP3959」 宝藏(爆搜

    题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 nn 个深埋在地下的宝藏屋, 也给出了这 nn 个宝藏屋之间可供开发的mm 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏. ...

  2. 【Lintcode】087.Remove Node in Binary Search Tree

    题目: Given a root of Binary Search Tree with unique value for each node. Remove the node with given v ...

  3. 一行代码解决IE6/7/8/9/10兼容问题

    百度源代码如下 <!Doctype html><html xmlns=http://www.w3.org/1999/xhtml xmlns:bd=http://www.baidu.c ...

  4. js 元素的各种宽度高度

    一.属性 1.只读属性 所谓的只读属性指的是DOM节点的固有属性,该属性只能通过js去获取而不能通过js去设置,而且获取的值是只有数字并不带单位的(px,em等),如下: 1)clientWidth和 ...

  5. 塞尔达:旷野之息个人对比上古卷轴V:天际

    上古卷轴5是我之前玩过最优秀的作品.玩塞尔达的时候就有跟上古卷轴5比对,真的都是神作.两个游戏的自由度都是真的高. 主线剧情上,老滚5印象不深了,当时就知道战斗,只记住了开头砍头现场,还有奥杜因这个龙 ...

  6. [hdu3530]Subsequence (单调队列)

    题意:求在一段序列中满足m<=max-min<=k的最大长度. 解题关键:单调队列+dp,维护前缀序列的最大最小值,一旦大于k,则移动左端点,取max即可. #include<cst ...

  7. Excel添加水印

    Excel添加水印[源码下载] 步骤一:根据生成图片的类创建水印图片 步骤二: 代码在Excel中根据第一行获取sheet的列数[sheet.getRow(0).getLastCellNum() ], ...

  8. JSP+JavaBean+Servlet工作原理实例…

    JSP+JavaBean+Servlet工作原理实例讲解 首先,JavaBean和Servlet虽都是Java程序,但是是完全不同的两个概念.引用mz3226960提出的MVC的概念,即M-model ...

  9. yzm10的ACM集训小感

    7月30号,ACM集训进行了两周,一切都已on the right way.这时的我适时地从题海中探出头,其实除了刷题,也该写点什么来总结下过去.首先,在第一周里,我学习了数据结构,知道了STL这么一 ...

  10. MVC动态生成的表单:表单元素比较多 你就这样写

    MVC动态生成的表单:表单元素比较多 你就这样写: public ActionResult ShoudaanActionResult(FormCollection from,T_UserM user) ...