Zookeeper作为分布式的服务框架,虽然是java写的,但是强大的C#也可以连接使用。
C#要连接使用Zookeeper,需要借助第三方插件,而现在主要有两个插件可供使用,分别是ZooKeeperNetEx和Zookeeper.Net
Zookeeper.Net好像是是Apache官方提供的,但是5年没更新了,也就是说他依赖于.net framework,因此无法在.net core项目中使用
ZooKeeperNetEx是从java改过来的,因此里面的一些习惯是java风格的,但是好像有人在提供更新维护,支持最新的Zookeeper特性,而且摆脱了对.net framework的依赖,所以个人推荐使用ZooKeeperNetEx做开发,本文也已介绍ZooKeeperNetEx为主
新建一个控制台项目,在nuget中搜索ZooKeeperNetEx,并安装最新版
在Program的Main方法:
using org.apache.zookeeper; using org.apache.zookeeper.data; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AspNetCore.ZookeeperConsole { class Program { static void Main(string[] args) { //Zookeeper连接字符串,采用host:port格式,多个地址之间使用逗号(,)隔开 string connectionString = "192.168.209.133:2181,192.168.209.133:2181,192.168.209.133:2181"; //会话超时时间,单位毫秒 int sessionTimeOut = 10000; //异步监听 var watcher = new MyWatcher("ConnectWatcher"); //连接 ZooKeeper zooKeeper = new ZooKeeper(connectionString, sessionTimeOut, watcher); Thread.Sleep(1000);//停一秒,等待连接完成 while (zooKeeper.getState() == ZooKeeper.States.CONNECTING) { Console.WriteLine("等待连接完成..."); Thread.Sleep(1000); } var state = zooKeeper.getState(); if (state != ZooKeeper.States.CONNECTED && state != ZooKeeper.States.CONNECTEDREADONLY) { Console.WriteLine("连接失败:" + state); Console.ReadKey(); return; } //创建znode节点 { var data = Encoding.UTF8.GetBytes("hello world"); List<ACL> acl = ZooDefs.Ids.OPEN_ACL_UNSAFE;//创建节点时的acl权限,也可以使用下面的自定义权限 //List<ACL> acl = new List<ACL>() { // new ACL((int)ZooDefs.Perms.READ, new Id("ip", "127.0.0.1")), // new ACL((int)(ZooDefs.Perms.READ | ZooDefs.Perms.WRITE), new Id("auth", "id:pass")) //}; CreateMode createMode = CreateMode.PERSISTENT; zooKeeper.createAsync("/mynode", data, acl, createMode).Wait(); Console.WriteLine("完成创建节点"); } //节点是否存在 { var exists = zooKeeper.existsAsync("/mynode", new MyWatcher("ExistsWatcher")).GetAwaiter().GetResult(); Console.WriteLine("节点是否存在:" + exists); } //获取节点数据 { var dataResult = zooKeeper.getDataAsync("/mynode", new MyWatcher("GetWatcher")).GetAwaiter().GetResult(); var value = Encoding.UTF8.GetString(dataResult.Data); Console.WriteLine("完成读取节点:" + value); } //设置节点数据 { var data = Encoding.UTF8.GetBytes("hello world again"); zooKeeper.setDataAsync("/mynode", d<span>本文来源gaodai#ma#com搞*!代#%^码网5</span>ata); Console.WriteLine("设置节点数据"); } //重新获取节点数据 { var dataResult = zooKeeper.getDataAsync("/mynode", new MyWatcher("GetWatcher")).GetAwaiter().GetResult(); var value = Encoding.UTF8.GetString(dataResult.Data); Console.WriteLine("重新获取节点数据:" + value); } //移除节点 { zooKeeper.deleteAsync("/mynode").Wait(); Console.WriteLine("移除节点"); } Console.WriteLine("完成"); Console.ReadKey(); } } class MyWatcher : Watcher { public string Name { get; private set; } public MyWatcher(string name) { this.Name = name; } public override Task process(WatchedEvent @event) { var path = @event.getPath(); var state = @event.getState(); Console.WriteLine($"{Name} recieve: Path-{path} State-{@event.getState()} Type-{@event.get_Type()}"); return Task.FromResult(0); } } }