Thrift 客户端 C# ---实现zookeeper监视(1)
来源:互联网 发布:大数据神经网络 编辑:程序博客网 时间:2024/05/29 05:01
干货---实现思路:RPC Thrift 服务端 注册服务端信息到zookeeper上。客户端从zookeeper获取服务端信息,并实现负载。
经验---注意事项。
Thrift服务端
使用ZooKeeperNet nugget包。
使用zookeeper的坑,
1、)没有zookeeper.open的方法。
2、)zookeeper 实例化【new ZooKeeper(connectstring, sessionTimeout, watcher);】后,连接CONNECTED并不是同步的。
zookeeper监视,使用一次后就失效。坑
1)、zookeeper 监视某个节点,无论增加删除等操作,一律都只有EventType.NodeChildrenChanged。
2)想检测某个末端节点,使用【_zookeeper.Exists方法即可】。
功能:
1)实现简单负载,轮询负载。随机负载。
2)实现从监视节点取出服务器节点信息。
3)长连接线程池未实现。可以去掉。
4)实现自动释放socket连接资源避免,线上出问题。
使用 public static Client GetSingleInstance(string rpcServicenamespace) 实列化,负载才能正常使用。
public class Client : IDisposable { /// <summary> /// 客户端池-根据不同业务自动选择对应业务客户端 /// </summary> static Dictionary<string, Client> _clientPool = new Dictionary<string, Client>(); /// <summary> ///客户端-TBufferedTransport /// </summary> internal Dictionary<string, TBufferedTransport> _tBufferedTransportPool = new Dictionary<string, TBufferedTransport>(); /// <summary> /// zookeeper注册唯一标识 /// </summary> private string _rpcServicenamespace = null;//"XXXX.XXXX.RegionCityRPC" /// <summary> /// 使用一个zookeeper客户端 /// </summary> private static ZooKeeper _zookeeper = null; /// <summary> /// 多线程锁 /// </summary> internal static object _look = new object(); /// <summary> /// zookeeper-所有监视节点 /// </summary> public IEnumerable<string> _nodeChildren = null; /// <summary> /// 轮询负载计数器 /// </summary> private int CountLoadbalance = 0; /// <summary> /// 构造函数 /// </summary> /// <param name="rpcServicenamespace"></param> public Client(string rpcServicenamespace) { this._rpcServicenamespace = rpcServicenamespace; } /// <summary> /// 获取一个唯一实例 /// </summary> /// <param name="key"></param> /// <returns></returns> public static T GetSingleInstance<T>(Dictionary<string, T> dictionary, string key, T t) where T : class { if (!dictionary.Keys.Contains(key)) { lock (_look) { if (!dictionary.Keys.Contains(key)) { TBufferedTransport tbufferedTransport = t as TBufferedTransport; //if (t != null) //{ // try // { // tbufferedTransport.Open(); // } // catch (Exception e) // { // Console.WriteLine("初始化TBufferedTransport连接异常!"); // } //} dictionary.Add(key, t); } } } return dictionary[key]; } /// <summary> /// 获取一个唯一实例 /// </summary> /// <param name="rpcServicenamespace"></param> /// <returns></returns> public static Client GetSingleInstance(string rpcServicenamespace) { /* if (!_clientPool.Keys.Contains(rpcServicenamespace)) { lock (_look) { if (!_clientPool.Keys.Contains(rpcServicenamespace)) { _clientPool.Add(rpcServicenamespace, new Client(rpcServicenamespace)); } } } return _clientPool[rpcServicenamespace]; */ return GetSingleInstance<Client>(_clientPool, rpcServicenamespace, new Client(rpcServicenamespace)); } //public void FilterTBufferedTransportPool(Client client) //{ // foreach (var item in client._tBufferedTransportPool) // { // item.Value.IsOpen // } //} /// <summary> /// 获取baoxian/appSettings配置 /// </summary> /// <returns></returns> private static NameValueCollection GetConfig() { return (NameValueCollection)ConfigurationManager.GetSection("baoxian/appSettings"); } /// <summary> /// 初始化 /// </summary> public void Init() { CreateZookeeperClient(); } /// <summary> /// 创建一个zookeeper客户端 /// </summary> /// <returns></returns> public ZooKeeper CreateZookeeperClient() { string connectstring = GetConfig()["ZookeeperConnectString"];// "192.168.1.3:2331 TimeSpan sessionTimeout = new TimeSpan(0, 0, 60); var watcher = new ClientWatcher(_rpcServicenamespace); if (_zookeeper == null)//单线程 { lock (_look) { if (_zookeeper == null)//多线程 { _zookeeper = new ZooKeeper(connectstring, sessionTimeout, watcher); string path = string.Format(GetConfig()[_rpcServicenamespace], _rpcServicenamespace);//string.Format("/test/servicecenter-dev/services/{0}/providers", "YinXin.BaoXian.UserOrderCount"); int count = 0; while (true) { Console.WriteLine("_zookeeper 重连次数:" + count); count++; System.Threading.Thread.Sleep(1000);//zookeeper的这个第三方有个坑。1、)没有zookeeper.open的方法。2、)zookeeper 实例化【new ZooKeeper(connectstring, sessionTimeout, watcher);】后,连接CONNECTED并不是同步的。 if (_zookeeper.State == ZooKeeper.States.CONNECTED) { GetChildrenWatcher();//zookeeper监视,使用一次后就失效。坑1)、zookeeper 监视某个节点,无论增加删除等操作,一律都只有EventType.NodeChildrenChanged。2)想检测某个末端节点,使用【_zookeeper.Exists方法即可】。 break; } if (count >= 60)//这里大于1分钟连接不上 { Logs.WriteLogInfo("_zookeeper网络连接可能有问题!"); Console.WriteLine("_zookeeper网络连接可能有问题!"); break; } } /* watcher.WaitUntilConnected(); while (true) { System.Threading.Thread.Sleep(5000); var tt = _zookeeper.GetChildren(path, watcher); var aa = tt + "333"; }*/ } } } return _zookeeper; } /// <summary> /// 客户端监视-想监视的节点 /// </summary> public void GetChildrenWatcher() { string path = string.Format(GetConfig()[_rpcServicenamespace], _rpcServicenamespace);//string.Format("/test/servicecenter-dev/services/{0}/providers", "XXX.XXX.UserOrderCount"); //var watcher = new ClientWatcher(); IEnumerable<string> nodeChildren = null; bool isError = false; try { nodeChildren = _zookeeper.GetChildren(path, true); } catch (Exception e) { Console.WriteLine(e.StackTrace); isError = true; } if (!isError) { lock (_look) { _nodeChildren = nodeChildren; } } if (nodeChildren == null) { return; } foreach (var item in nodeChildren) { _zookeeper.Exists(path + "/" + item, true); } } /// <summary> /// 随机 /// </summary> /// <returns></returns> public string Random() { IEnumerable<string> nodeChildren = null; if (_nodeChildren != null) { lock (_look) { nodeChildren = _nodeChildren; } } Random random = new Random(); int count = nodeChildren.Count(); if (count == 0) { return "false"; } int index = random.Next(0, nodeChildren.Count() - 1); return nodeChildren.ToList()[index]; } /// <summary> /// 根据负载服务器生成TBufferedTransport /// </summary> /// <returns></returns> public TBufferedTransport GetTSocket(string servers) { //string servers = thriftClient.Random();//随机负载 if (string.IsNullOrWhiteSpace(servers)) { return null; } var list = servers.Split(':'); if (list.Count() == 2) { //var tbufferedTransport = GetSingleInstance<TBufferedTransport>(_tBufferedTransportPool, servers, new TBufferedTransport(new TSocket(list[0], int.Parse(list[1])))); return GetSingleInstance<TBufferedTransport>(_tBufferedTransportPool, servers, new TBufferedTransport(new TSocket(list[0], int.Parse(list[1])))); } else { return null; } } /// <summary> /// 轮询 /// </summary> /// <returns></returns> public string Loadbalance() { int index = 0; IEnumerable<string> nodeChildren = null; if (_nodeChildren != null) { lock (_look) { nodeChildren = _nodeChildren; CountLoadbalance++; CountLoadbalance = CountLoadbalance > _nodeChildren.Count() ? 1 : CountLoadbalance; index = CountLoadbalance; } } if (index - 1 >= 0 && nodeChildren != null && nodeChildren.Count() != 0) { return nodeChildren.ToList()[index - 1]; } else { Console.WriteLine("轮询--无节点"); Logs.WriteLogInfo("轮询--无节点"); return "轮询无节点"; } } /// <summary> /// Dispose /// </summary> public void Dispose() { //关闭并销毁长连接 _zookeeper.Dispose(); foreach (var item in this._tBufferedTransportPool) { item.Value.Close(); item.Value.Dispose(); } //throw new NotImplementedException(); } } /// <summary> /// zookeeper 监测事件实现 /// </summary> internal class ClientWatcher : IWatcher { private Client client; //private readonly ManualResetEventSlim _connected = new ManualResetEventSlim(false); //private WatchedEvent _event; public ClientWatcher(string _rpcServicenamespace) { client = Client.GetSingleInstance(_rpcServicenamespace); } //public void WaitUntilConnected() //{ // _connected.Wait(); // if (_event == null) throw new ApplicationException("bad state"); // if (_event.State != KeeperState.SyncConnected) // throw new ApplicationException("cannot connect"); //} /// <summary> /// 实现Process监控事件 /// </summary> /// <param name="event"></param> public void Process(WatchedEvent @event) { //_event = @event; switch (@event.State) { case KeeperState.Disconnected: break; case KeeperState.Expired: break; case KeeperState.NoSyncConnected: break; case KeeperState.SyncConnected: //_connected.Set(); break; case KeeperState.Unknown: break; default: break; } switch (@event.Type) { case EventType.NodeChildrenChanged: client.GetChildrenWatcher();//监测节点 Console.Write(" EventType.NodeChildrenChanged"); break; case EventType.NodeCreated: Console.Write("EventType.NodeCreated:"); break; case EventType.NodeDataChanged: Console.Write("EventType.NodeDataChanged:"); break; case EventType.NodeDeleted: if (!string.IsNullOrWhiteSpace(@event.Path)) { #region socket 长连接时使用,慎用 string path = @event.Path.Substring(0, @event.Path.LastIndexOf('/')); string name = @event.Path.Substring(@event.Path.LastIndexOf('/') + 1); lock (Client._look) { client._tBufferedTransportPool[name].Close(); client._tBufferedTransportPool[name].Dispose(); client._tBufferedTransportPool.Remove(name); } #endregion } Console.Write("EventType.NodeDeleted:"); break; case EventType.None: Console.Write("EventType.None:"); break; default: break; } } }
阅读全文
0 0
- Thrift 客户端 C# ---实现zookeeper监视(1)
- Thrift 客户端 C# ---从zookeeper获取服务器信息、实现负载(2)
- C#实现Thrift服务端与客户端
- Flume C# Thrift客户端
- Thrift交流(二)thrift服务端和客户端实现 Nifty
- Thrift交流(二)thrift服务端和客户端实现 Nifty
- Thrift学习笔记(4)--实现Thrift客户端连接池
- Thrift交流(二)thrift服务端和客户端实现 Nifty
- Android和C#实现Thrift服务端和客户端
- RPC入门总结(七)Thrift+Zookeeper实现服务治理
- Thrift 双向通信实现(C#版)
- 实现Thrift客户端连接池
- Thrift学习笔记(6)--Spring集成Thrift,实现服务端和客户端代理
- Zookeeper JAVA客户端(Kotlin 实现) CRUD
- zookeeper 客户端的实现
- ZooKeeper客户端--java实现
- 【zookeeper】客户端 底层实现
- NET(C#)接入Dubbo服务,Zookeeper作为Dubbo服务的注册中心,实现thrift协议访问接口(1)
- 《大话设计模式》java实现之简单工厂模式
- ACM准备之路(蓝桥杯4)杨辉三角数组解法
- PHP四级联动全国地区
- 打包状态下百度的ak的获得
- 回文算法
- Thrift 客户端 C# ---实现zookeeper监视(1)
- 大数据预科19(补充之线程)
- C#简单的在图片上添加文字并保存
- 再谈找负环
- UVa 10370 Above Average
- ACM准备之路(蓝桥杯5)杨辉三角公式解法
- 浅谈DMA
- Mybatis源码(三)之SqlSession执行流程全貌
- JAVA项目中数据库表的设计思路