/// <summary> /// start /// </summary> public void Start() { if (this._config == null || this._config.Registry == null || this._config.Registry.Zookeeper == null) return; var keeperConfig = this._config.Registry.Zookeeper; var zk = ZookClientPool.Get(keeperConfig.ConfigPath, "zookeeper", keeperConfig.ConfigName); //ensure root node... var nodes = new NodeInfo[2]; nodes[0] = new NodeInfo(string.Concat("/", keeperConfig.ZNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent); nodes[1] = new NodeInfo(string.Concat("/", keeperConfig.ZNode, "/providers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent); NodeFactory.TryEnsureCreate(zk, nodes, () => { var currProcess = Process.GetCurrentProcess(); var path = string.Concat("/", keeperConfig.ZNode, "/providers/", Uri.EscapeDataString(string.Format( "thrift2://{0}:{1}/{2}?anyhost=true&application={3}&dispatcher=message&dubbo=2.5.1&interface={2}&loadbalance=roundrobin&methods={7}&owner={4}&pid={5}&revision=0.0.2-SNAPSHOT&side=provider&threads=100×tamp={6}", IPUtility.GetLocalIntranetIP().ToString(), this._config.Port.ToString(), keeperConfig.ZNode, currProcess.ProcessName, keeperConfig.Owner, currProcess.Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), this._methods))); this._sessionNode = new SessionNode(zk, path, null, IDs.OPEN_ACL_UNSAFE); }); }
/// <summary> /// start /// </summary> public void Start() { if (this._config == null || this._config.Discovery == null || this._config.Discovery.Zookeeper == null || string.IsNullOrEmpty(this._config.Discovery.Zookeeper.ZNode)) return; var keeperConfig = this._config.Discovery.Zookeeper; var zk = ZookClientPool.Get(keeperConfig.ConfigPath, "zookeeper", keeperConfig.ConfigName); //ensure root node... var nodes = new NodeInfo[2]; nodes[0] = new NodeInfo(string.Concat("/", keeperConfig.ZNode), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent); nodes[1] = new NodeInfo(string.Concat("/", keeperConfig.ZNode, "/consumers"), null, IDs.OPEN_ACL_UNSAFE, CreateModes.Persistent); NodeFactory.TryEnsureCreate(zk, nodes, () => { var currProcess = Process.GetCurrentProcess(); var path = string.Concat("/", keeperConfig.ZNode, "/consumers/", Uri.EscapeDataString(string.Format( "consumer://{0}/{1}?application={2}&category=consumers&check=false&dubbo=2.5.1&interface={1}&methods={6}&owner={3}&pid={4}&revision=0.0.2-SNAPSHOT&side=consumer×tamp={5}", IPUtility.GetLocalIntranetIP().ToString(), keeperConfig.ZNode, currProcess.ProcessName, string.Empty, currProcess.Id.ToString(), Date.ToMillisecondsSinceEpoch(DateTime.UtcNow).ToString(), this._methods))); this._sessionNode = new SessionNode(zk, path, null, IDs.OPEN_ACL_UNSAFE); }); this._watcher = new ChildrenWatcher(zk, string.Concat("/", keeperConfig.ZNode, "/providers"), (names) => { //已存在的servers var arrExistServers = this._thriftClient.GetAllNodeNames(); //当前从zk获取到servers var arrNowServers = names.Select(s => { var t = Uri.UnescapeDataString(s); t = t.Substring(t.IndexOf(":") + 3); return t.Substring(0, t.IndexOf("/")); }).ToArray(); var set = new HashSet<string>(arrExistServers); set.ExceptWith(arrNowServers); if (set.Count > 0) { foreach (var child in set) this._thriftClient.UnRegisterServerNode(child); } set = new HashSet<string>(arrNowServers); set.ExceptWith(arrExistServers); if (set.Count > 0) { foreach (var child in set) { int index = child.IndexOf(":"); this._thriftClient.RegisterServerNode(child, new IPEndPoint(IPAddress.Parse(child.Substring(0, index)), int.Parse(child.Substring(index + 1)))); } } }); }
/// <summary> /// register zk node /// </summary> /// <param name="arrNodes"></param> private void RegisterZNode(NodeInfo[] arrNodes) { NodeCreator.TryCreate(this._zk, arrNodes).ContinueWith(c => { if (Thread.VolatileRead(ref this._isdisposed) == 1) return; TaskEx.Delay(new Random().Next(100, 1500)).ContinueWith(_ => this.RegisterZNode(arrNodes)); }, TaskContinuationOptions.OnlyOnFaulted); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <returns></returns> static public Task TryCreate(IZookClient zk, NodeInfo[] nodes) { if (zk == null) throw new ArgumentNullException("zk"); if (nodes == null || nodes.Length == 0) throw new ArgumentNullException("nodes"); var source = new TaskCompletionSource<bool>(); TryCreate(zk, nodes, 0, source); return source.Task; }
/// <summary> /// new /// </summary> /// <param name="zk"></param> /// <param name="path"></param> /// <param name="data"></param> /// <param name="acl"></param> /// <exception cref="ArgumentNullException">zk is null.</exception> public SessionNode(IZookClient zk, string path, byte[] data, Data.ACL[] acl) { if (zk == null) throw new ArgumentNullException("zk"); this._zk = zk; this._zk.KeeperStateChanged += new KeeperStateChangedHandler(this.KeeperStateChanged); this._nodeInfo = new NodeInfo(path, data, acl, Data.CreateModes.Ephemeral); this.CreateNode(); }
/// <summary> /// try create node /// </summary> /// <param name="zk"></param> /// <param name="node"></param> /// <returns></returns> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">node is null.</exception> static public Task TryCreate(IZookClient zk, NodeInfo node) { if (zk == null) throw new ArgumentNullException("zk"); if (node == null) throw new ArgumentNullException("node"); return zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { var ex = c.Exception.InnerException as KeeperException; if (ex != null && ex.Error == Data.ZoookError.NODEEXISTS) return; throw c.Exception.InnerException; }, TaskContinuationOptions.OnlyOnFaulted); }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> static private void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, int index, Action callback) { if (index >= nodes.Length) { if (callback != null) callback(); return; } var currNode = nodes[index]; zk.Create(currNode.Path, currNode.Data, currNode.ACL, currNode.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var kex = c.Exception.InnerException as KeeperException; if (kex == null || kex.Error != Data.ZoookError.NODEEXISTS) { TaskEx.Delay(new Random().Next(1000, 3000), () => TryEnsureCreate(zk, nodes, index, callback)); return; } } TryEnsureCreate(zk, nodes, index + 1, callback); }); }
/// <summary> /// try create nodes /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="index"></param> /// <param name="source"></param> static private void TryCreate(IZookClient zk, NodeInfo[] nodes, int index, TaskCompletionSource<bool> source) { if (index >= nodes.Length) { source.TrySetResult(true); return; } var node = nodes[index]; zk.Create(node.Path, node.Data, node.ACL, node.CreateMode).ContinueWith(c => { if (c.IsFaulted) { var ex = c.Exception.InnerException as KeeperException; if (ex == null || ex.Error != Data.ZoookError.NODEEXISTS) { source.TrySetException(c.Exception.InnerException); return; } } TryCreate(zk, nodes, index + 1, source); }); }
/// <summary> /// 批量创建一组节点 /// </summary> /// <param name="zk"></param> /// <param name="nodes"></param> /// <param name="callback">当所有节点创建完毕时的回调</param> /// <exception cref="ArgumentNullException">zk is null.</exception> /// <exception cref="ArgumentNullException">nodes is null or empty.</exception> static public void TryEnsureCreate(IZookClient zk, NodeInfo[] nodes, Action callback) { if (zk == null) throw new ArgumentNullException("zk"); if (nodes == null || nodes.Length == 0) throw new ArgumentNullException("nodes"); TryEnsureCreate(zk, nodes, 0, callback); }
/// <summary> /// 创建节点 /// </summary> /// <param name="zk"></param> /// <param name="node"></param> /// <param name="callback"></param> static public void TryEnsureCreate(IZookClient zk, NodeInfo node, Action callback) { TryEnsureCreate(zk, new NodeInfo[] { node }, callback); }