zk实现服务选举
非公平选举算法
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实现服务选举的更多相关文章
- 基于Lease分布式系统重试服务选举
		/** * Copyright (c) 2015, www.cubbery.com. All rights reserved. */ package com.cubbery.event.retry; ... 
- dubbo zk 分布式服务项目搭建与配置
		1. 项目 jar -----提供接口 2. 项目 jar -----接口实现 provider启动zk main方法启动 start applicationContext.xml <b ... 
- springboot 注册服务注册中心(zk)的两种方式
		在使用springboot进行开发的过程中,我们经常需要处理这样的场景:在服务启动的时候,需要向服务注册中心(例如zk)注册服务状态,以便当服务状态改变的时候,可以故障摘除和负载均衡. 我遇到过两种注 ... 
- zookeeper篇-zk的选举机制
		点赞再看,养成习惯,微信搜索「小大白日志」关注这个搬砖人. 文章不定期同步公众号,还有各种一线大厂面试原题.我的学习系列笔记. 说说zk的选举机制 基础概念 zxid=事务id=一个时间戳,代表当前事 ... 
- Dubbo+ZK与Eureka注册中心比较
		Eureka可以很好的应对网络故障导致部分节点失去联系的情况,而不会像zk那样因为选举导致整个集群不可用 dubbo + zk 当向注册中心查询服务注册列表时,可以容忍注册中心返回的是几分钟以前的注册 ... 
- zookeeper分布式锁和服务优化配置
		转自:https://www.jianshu.com/p/02eeaee4357f?utm_campaign=maleskine&utm_content=note&utm_medium ... 
- Zookeeper实现Master选举(哨兵机制)
		master选举使用场景及结构 现在很多时候我们的服务需要7*24小时工作,假如一台机器挂了,我们希望能有其它机器顶替它继续工作.此类问题现在多采用master-salve模式,也就是常说的主从模式, ... 
- hadoop系列:zookeeper(2)——zookeeper核心原理(选举)
		1.前述 上篇文章<hadoop系列:zookeeper(1)--zookeeper单点和集群安装>(http://blog.csdn.net/yinwenjie/article/deta ... 
- zookeeper分布式协调服务的使用一
		Zookeeper是一个高性能,分布式的应用协调服务. 提供服务: 1.集群成员的管理(Group Membership) 2.分布式锁(Locking) 3.选主(Leader Election) ... 
随机推荐
- WebSocket的C++服务器端实现
			由于需要在项目中增加Websocket协议,与客户端进行通信,不想使用开源的库,比如WebSocketPP,就自己根据WebSocket协议实现一套函数,完全使用C++实现. 代码已经实现,放在个人g ... 
- 百度地图API的第一次接触
			因为项目的需求,第一次接触了百度API. 第一步:引用百度地图API的脚本 如果在局域网环境中,要把地图文件和js文件都要下载下来 <script type="text/javascr ... 
- noip2013提高组:积木大赛
			题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第n块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ... 
- SpringMVC之四:渲染Web视图
			理解视图解析 在前面的例子中,我们看到控制器返回的都是一个逻辑视图的名称,然后把这个逻辑视图名称交给view resolver,然后返回渲染后的 html 页面给 client. 将控制器中请求处理的 ... 
- 用位运算实现四则运算之加减乘除(用位运算求一个数的1/3) via Hackbuteer1
			转自:http://blog.csdn.net/hackbuteer1/article/details/7390093 ^: 按位异或:&:按位与: | :按位或 计算机系统中,数值一律用补码 ... 
- nohup开机自启脚本
			#!/bin/bash cd /root/xcloud/ str=$"/n" sstr=$(echo -e $str) nohup ./deploy >>/dev/nu ... 
- xml约束(转)
			在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束. 常用的约束技术XML DTD :XML Schema. XML Schema 也是一种用于定义和描述 XML 文档 ... 
- 将Angular6自己定义的模块发布成npm包
			创建自己的模块组件 1. ng new 一个工程 2. ng g m 创建模块 例如我这里的modules文件下创建header模块 3. ng g c modules/head 创建一个hear组件 ... 
- Golang : cobra 包简介
			Cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序.同时,Cobra 也是一个应用程序,用来生成应用框架,从而开发以 Cobra 为基础的应用.本文的演示环境为 ubuntu 1 ... 
- ue4 官网IK流程记录
			基本流程 角色蓝图构造 角色蓝图 角色蓝图中新建的函数IK Foot Trace AnimGraph事件 这里注意下Make Vector时把z方向的偏移量设置到了X上 猜测原因是效应器的x方向跟世界 ... 
