zookeeper.recipes.leader (C#)
来源:互联网 发布:java版的aes加密算法 编辑:程序博客网 时间:2024/06/09 23:09
近来有项目要用到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设置)
源码下载
- zookeeper.recipes.leader (C#)
- Zookeeper-Zookeeper leader选举
- Zookeeper-Zookeeper leader选举
- Zookeeper-Zookeeper leader选举
- Zookeeper-Zookeeper leader选举
- Zookeeper-Zookeeper leader选举
- Zookeeper-Zookeeper leader选举
- ZooKeeper源码阅读(五):Leader选举
- zookeeper——leader选举(curator)
- Zookeeper系列(三十三)Zookeeper之leader选举算法补充
- zookeeper LeaderElection(leader 选举)
- ZooKeeper leader election
- zookeeper leader选举
- leader election with zookeeper
- Zookeeper -- leader选举
- zookeeper选举leader过程
- zookeeper leader作用
- zookeeper-Leader选举
- Androidstudio jar 包 位置以及 source
- 基于注解和反射的Java ORM框架(1)-通过注解描述映射关系
- Java C++ 读写文件大小端格式是不同的
- Spring + Junit
- pwnable.kr [Toddler's Bottle]
- zookeeper.recipes.leader (C#)
- Hibernate框架中的事务(隔离等级设置、事务提交、事务回滚)
- Linux环境下配置搭建Redis分布式集群
- 【MyBatis学习04】mapper代理方法开发dao
- 【MyBatis学习04】mapper代理方法开发dao
- linux shell dash&bash
- BZOJ P2241[sdoi2011]打地鼠
- Android 通过form表单上传文字,图片,视频等(通过key值)以及问题分析
- C++标准库之<iomanip>