关闭

zookeeper.recipes.leader (C#)

标签: zookeeperelection选举
677人阅读 评论(0) 收藏 举报
分类:

近来有项目要用到zookeeper的选举实现,研究了下后在此做下记录

首先下载zookeeper的recipes实现,nuget地址:https://www.nuget.org/packages/ZooKeeperNetEx.Recipes/

选举实现逻辑描述可见http://zookeeper.apache.org/doc/r3.4.9/recipes.html#sc_leaderElection需要注意的是:监控到节点变更时,当前节点不一定就会成为Leader,因为也有可能是非Leader节点发生了变更,这时需要调整监控节点为变更节点的上一个节点

选举实现在org.apache.zookeeper.recipes.leader命名空间下,该空间下公开有接口LeaderElectionAware,选举状态枚举ElectionEventType,以及选举实现类LeaderElectionSupport

LeaderElectionSupport

LeaderElectionSupport只提供了一个构造函数,该函数包含3个参数,分别为

ZooKeeper zooKeeper:选举实现依赖于zookeeper,该参数就是用来进行选举的zookeeper

string rootNodeName:用于选举的zookeeper根节点路径,注意该节点必须已经存在,选举类并不会自动创建此节点,且根节点需是持久化(PERSISTENT)节点

string hostName:当前参与选举的服务名称,注意该名称可以重名(即所有选举服务器都可以用同一个名字,但这样会导致getLeaderHostName获取到的名称无法区分服务器,所以这里建议设置为唯一值,最好设置为对外host地址)

LeaderElectionSupport公开了5个方法:addListener、removeListener、start、stop以及getLeaderHostName

addListener和removeListener用来添加、移除选举状态监控,其参数均为LeaderElectionAware实现

start和stop对应开始选举和结束并退出选举

getLeaderHostName为获取当前选举为Leader的hostName


LeaderElectionAware

LeaderElectionAware只定义了一个方法onElectionEvent,该方法参数为ElectionEventType,在通过addListener添加选举监控后,当选举状态发生任意变化时,都会执行onElectionEvent方法,这时可通过参数ElectionEventType来确认当前的选举状态,下面会对各选举状态的触发情况进行描述


ElectionEventType

ElectionEventType列举的状态一般都是成对出现,包含START和COMPLETE

ElectionEventType.START 选举开始,表示执行了LeaderElectionSupport的start方法

ElectionEventType.STOP_START 结束选举并退出,表示执行了LeaderElectionSupport的stop方法

ElectionEventType.STOP_COMPLETE 与ElectionEventType.STOP_START对应,实际监控时只需监控两者之一,在stop时,选举方法会尝试删除当前应用对应的zookeeper临时节点,如果异常则会触发ElectionEventType.FAILED(但不管是否异常,都会触发ElectionEventType.STOP_START)

ElectionEventType.OFFER_START 启动时为本地注册对应znode节点,触发于start方法

ElectionEventType.OFFER_COMPLETE 对应ElectionEventType.OFFER_START,实际监控时只需监控两者之一

ElectionEventType.DETERMINE_START 开始判断本机是否可以成为Leader,一般发生在第一次执行start方法时,或者监控到节点变更时

ElectionEventType.DETERMINE_COMPLETE 判断结束,后面会根据判断结果执行ELECTED或READY

ElectionEventType.ELECTED_START 表示当前服务当选为Leader

ElectionEventType.ELECTED_COMPLETE 与ElectionEventType.ELECTED_START对应,实际监控时只需监控两者之一

ElectionEventType.READY_START 开始就绪确认,表示开始执行Ready流程

ElectionEventType.READY_COMPLETE 表示Ready流程结束,已成功监控前一个节点,注意ElectionEventType.READY_COMPLETE与ElectionEventType.READY_START并不一定成对出现,有可能在Ready流程中,当发现当前应用监控的节点丢失时,会重新开始选举,即触发ElectionEventType.DETERMINE_START

ElectionEventType.FAILED 表示选举异常,可能发生在start,stop,以及监控到变更,触发选举时


简单的使用demo如下

        //zookeeper地址
        static string connectionString = "127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183";
        //超时时间,单位毫秒
        static int timeOut = 2000;

        static async void ElectedDemo()
        {
            ZooKeeper zk = new ZooKeeper(connectionString, timeOut, new EmptyWatcher());
            string rootNodePath = "/zkRecipesRoot";
            int rd;
            do
            {
                rd = Guid.NewGuid().GetHashCode();
            }
            while (rd <= 0);
            //用于生成随机的hostName后缀,这里只是demo,所以不保证唯一性
            string hostName = "zkRecipesDemo" + new Random().Next(rd);
            Console.WriteLine("This hostName is:{0}", hostName);
            var stat = await zk.existsAsync(rootNodePath);
            if (stat == null)
            {
                //根节点需要自行创建,LeaderElectionSupport不会自动创建根节点
                await zk.createAsync(rootNodePath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            }
            LeaderElectionSupport support = new LeaderElectionSupport(zk, rootNodePath, hostName);
            support.addListener(new LeaderElectionAwareIpml(support));//该处可以注释表示不添加监控
            await support.start();
        }

EmptyWatcher是一个没任何实现的空监控,这里之所以要有这么一个实现,是因为如果在zookeeper的构造函数中传递null进去,虽然不会导致程序异常,但会在console界面输出空引用异常信息

    public class EmptyWatcher : Watcher
    {
        public override Task process(WatchedEvent @event)
        {
            return Task.FromResult(0);
        }
    }
LeaderElectionAwareIpml是对LeaderElectionAware的一个简单实现,该实现只监控了ElectionEventType.DETERMINE_START和ElectionEventType.READY_COMPLETE状态
    public class LeaderElectionAwareIpml : LeaderElectionAware
    {
        private LeaderElectionSupport _support;
        public LeaderElectionAwareIpml(LeaderElectionSupport support)
        {
            if (support == null)
            {
                throw new ArgumentNullException("LeaderElectionSupport");
            }
            this._support = support;
        }
        public async Task onElectionEvent(ElectionEventType eventType)
        {
            //这里只简单的监控ELECTED_START和READY_COMPLETE这两个具备代表性的状态
            //ELECTED_START监控当选
            //READY_COMPLETE监控就绪
            if (eventType == ElectionEventType.ELECTED_START
                /*|| eventType == ElectionEventType.ELECTED_COMPLETE*/)
            {
                Console.WriteLine("This host to be leader");
                await PrintElectionInfo();
            }
            else if (eventType == ElectionEventType.READY_COMPLETE)
            {
                Console.WriteLine("This host is ready");
                await PrintElectionInfo();
            }
        }
        private async Task PrintElectionInfo()
        {
            var leaderHostName = await this._support.getLeaderHostName();
            Console.WriteLine("The leader hostName is:{0}", leaderHostName);
            Console.WriteLine("******************* Current election info *******************");
            Console.WriteLine(this._support);
        }
    }
依次执行exe,可见下图,注意输出内容部分,另外如果短时间内反复打开、关闭可能会出现zookeeper的ConnectionLossException,这时稍等一段时间后再执行exe即可(具体等待多长时间取决于timeout设置)



源码下载


0
0
查看评论

c# .net 中<% = %>,<% # %>,<% $ %>意义

在asp.net中经常出现包含这种形式的html代码,总的来说包含下面这样几种格式: 一. 这种格式实际上就是和asp的用法一样的,只是asp中里面是vbscript或者javascript代码,而在asp.net中是.net平台下支持的语言。 特别注意:服务器控件中不能有语法 (这里用...
  • hws1058648831a
  • hws1058648831a
  • 2013-06-24 11:14
  • 1878

c#$用法

c#$的用法,c#6.0新特性$的用法
  • kebi007
  • kebi007
  • 2016-09-21 20:26
  • 16649

C#队列,优先级,Queue类

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Diagnostics; namesp...
  • u013010416
  • u013010416
  • 2013-12-17 16:12
  • 1779

快速排序算法-c#版

大多数程序员在写排序算法的时候,都会采用冒泡算法,为什么了?因为这个算法最简单,最容易理解,也最容易写。 但是,冒泡算法效率并不高,今天就写一个c#的快速排序算法。 废话不多说,先直接上代码: using System; using System.Collections.Generic; us...
  • mamihong
  • mamihong
  • 2012-12-18 11:49
  • 3625

c#里面 : this()是什么意思?

c#里面  : this()是什么意思? 在XAML文件里面,今天同事写了一行这样的代码public AddDOCRegister(DocRegister item)  : this() public partial class AddDOCRegister : Chil...
  • caikundashu
  • caikundashu
  • 2012-04-09 19:23
  • 5310

在C#中使用CURL

private string args = "";          ///         /// 参...
  • tg2003
  • tg2003
  • 2012-07-07 01:17
  • 10325

C# 常见加密解密类

大部分的加密类的使用方式是差不多的,其中MD5和SHA类似,均为不可逆;RSA位可加可解;DES和AES类似,均需要加密向量;文中所有明文加密后都转为了净荷明文。没必要转Byte转16进制字符串(难为不懂的?)!! 加密方式 加密向量 是否可逆 MD5、SHA 不需...
  • hotmee
  • hotmee
  • 2016-09-19 11:14
  • 5052

图形化开发c#

NET下的流程图开发包介绍 http://www.cnblogs.com/foundation/archive/2008/06/29/1232108.html 工作流程图、对象层次和关系图控件WpfDiagram  什么...
  • TheoGo
  • TheoGo
  • 2016-01-01 13:08
  • 1318

C# NamedPipe 命名管道通信

异步操作类:
  • Moxie_Yan
  • Moxie_Yan
  • 2014-10-30 15:50
  • 1649

C# 如何创建与读写txt文件

// 判断文件是否存在,不存在则创建,否则读取值显示到窗体             if (!File.Exists("F:\\TestTxt.txt"))      ...
  • fuzhenglai
  • fuzhenglai
  • 2016-11-14 13:49
  • 18435
    个人资料
    • 访问:385777次
    • 积分:4105
    • 等级:
    • 排名:第8951名
    • 原创:78篇
    • 转载:4篇
    • 译文:0篇
    • 评论:132条
    文章分类
    最新评论