Thrift 客户端 C# ---从zookeeper获取服务器信息、实现负载(2)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gzy11/article/details/78503015

干货---实现思路:RPC Thrift 服务端 注册服务端信息到zookeeper上。客户端从zookeeper获取服务端信息,并实现负载。
经验---注意事项。
如图:

Thrift 坑:

1)Thrift 二次封装的socket 使用   using (TBufferedTransport transport = new TBufferedTransport(GetTSocket())),会被活生生坑死。IDisposable中为实现close()..

所以必须使用如下代码, transport.Close();是重点

            using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
            {
                try
                {
                    transport.Open();
                    TProtocol protocol = new TBinaryProtocol(transport);
                    CityService.Client client = new CityService.Client(protocol);
                    return func(client);
                    //return "";
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                    return "fales:" + e.Message;
                }
                finally
                {
                    transport.Close();
                }
            }

经验:
     1)当zookeeper服务器节点信息如有异常服务时,会自动轮询可用RPC Thrift服务。(指无法连接RPC Thrift服务端,代码层面报错不在此范围内。)
     2)客户端实现注意去除异常服务器连接,如下代码实现。
        /// <summary>
        /// 记录error数
        /// </summary>
        private int errorCount = 0;
        /// <summary>
        /// 查询(包含保险公司是否可以投保) 
        /// </summary>
        /// <param name="query"></param>
        /// <param name="shortEName"></param>
        /// <returns></returns>
        public string GetQueryCitiesInfo(string query, string shortEName = null)
        {
            using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
            {
                try
                {
                    transport.Open();
                    TProtocol protocol = new TBinaryProtocol(transport);
                    CityService.Client client = new CityService.Client(protocol);
                    return client.getQueryCitiesInfo(query, shortEName);
                }
                catch (Exception e)
                {
                    errorCount++;
                    Console.WriteLine(e.StackTrace);
                    if (errorCount >= thriftClient._nodeChildren.Count())
                    {
                        Logs.WriteLogInfo("无可用服务!" + e.StackTrace);
                        errorCount = 0;
                        return null;
                    }
                    return GetQueryCitiesInfo(query, shortEName);
                }
                finally
                {
                    transport.Close();
                }
            }
        }



    
 public class ClientShort
    {
        /// <summary>
        /// 负载模式--枚举
        /// </summary>
        internal enum ConnectModel
        {
            /// <summary>
            /// 随机
            /// </summary>
            Random,
            /// <summary>
            /// 轮询
            /// </summary>
            Loadbalance,
        }
        /// <summary>
        /// 获取一个唯一类目的thriftClient(YiXin.BaoXian.Toolkits.Common.Thrift.Clien)
        /// </summary>
        private static YiXin.BaoXian.Toolkits.Common.Thrift.Client thriftClient = Toolkits.Common.Thrift.Client.GetSingleInstance("YinXin.BaoXian.RegionCityRPC");

        /// <summary>
        /// thrift TBufferedTransport()
        /// </summary>
        private static TBufferedTransport _TBufferedTransport;

        /// <summary>
        /// 记录error数
        /// </summary>
        private int errorCount = 0;

        /// <summary>
        /// thrift tsocket 
        /// </summary>
        private static TSocket _tsocket = null;

        /// <summary>
        /// 短连接-构造函数
        /// </summary>
        public ClientShort()
        {
            thriftClient.Init();
        }

        #region 测试可删除代码
        /// <summary>
        /// 委托实验--可删除
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        private string UsingTBufferedTransport(Func<CityService.Client, string> func)
        {
            using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
            {
                try
                {
                    transport.Open();
                    TProtocol protocol = new TBinaryProtocol(transport);
                    CityService.Client client = new CityService.Client(protocol);
                    return func(client);
                    //return "";
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                    return "fales:" + e.Message;
                }
                finally
                {
                    transport.Close();
                }
            }
        }
        /// <summary>
        /// 委托实验可删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="func"></param>
        /// <returns></returns>
        private string UsingTransport<T>(Func<T, string> func) where T : class
        {
            using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
            {
                try
                {
                    transport.Open();
                    TProtocol protocol = new TBinaryProtocol(transport);
                    CityService.Client client = new CityService.Client(protocol);
                    T t = client as T;
                    return func(t);
                    //return "";
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.StackTrace);
                    return "fales:" + e.Message;
                }
                finally
                {
                    transport.Close();
                }
            }
        }

        /// <summary>
        /// 委托实验调用时更简洁,性能会有影响。
        /// </summary>
        /// <param name="shortEName"></param>
        /// <returns></returns>
        public string GetCityInfoList1__Test(string shortEName = null)
        {
            return UsingTransport<CityService.Client>((client) =>
            {
                return client.getCityInfoList(shortEName);
            });
        }

        /// <summary>
        /// 选择负载模式
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private TBufferedTransport GetTBufferedTransport(ConnectModel model)
        {
            string servers = null;
            switch (model)
            {
                case ConnectModel.Random:
                    servers = thriftClient.Random();
                    break;
                case ConnectModel.Loadbalance:
                    servers = thriftClient.Loadbalance();
                    break;
                default:
                    break;
            }

            Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + servers);
            TBufferedTransport transport = thriftClient.GetTSocket(servers);

            try
            {
                if (!transport.IsOpen)
                    transport.Open();
            }
            catch (Exception e)
            {

                Console.Write("寻找可用客户端");
                errorCount++;
                if (errorCount >= thriftClient._nodeChildren.Count())
                {
                    Logs.WriteLogInfo("寻找可用客户端" + e.StackTrace);
                    return null;
                }
                return GetTBufferedTransport(ConnectModel.Loadbalance);//轮询
            }

            _TBufferedTransport = transport;
            errorCount = 0;
            return _TBufferedTransport;
        }
        #endregion

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="query"></param>
        /// <param name="shortEName"></param>
        /// <returns></returns>
        public string GetQueryCitiesInfo(string query, string shortEName = null)
        {
            using (TBufferedTransport transport = new TBufferedTransport(GetTSocket()))
            {
                try
                {
                    transport.Open();
                    TProtocol protocol = new TBinaryProtocol(transport);
                    CityService.Client client = new CityService.Client(protocol);
                    return client.getQueryCitiesInfo(query, shortEName);
                }
                catch (Exception e)
                {
                    errorCount++;
                    Console.WriteLine(e.StackTrace);
                    if (errorCount >= thriftClient._nodeChildren.Count())
                    {
                        Logs.WriteLogInfo("无可用服务!" + e.StackTrace);
                        errorCount = 0;
                        return null;
                    }
                    return GetQueryCitiesInfo(query, shortEName);
                }
                finally
                {
                    transport.Close();
                }
            }
        }
}

 
 

 
 

 
 
 

猜你喜欢

转载自blog.csdn.net/gzy11/article/details/78503015