Beispiel #1
0
        /// <summary>
        /// 归还连接池
        /// </summary>
        /// <param name="transport"></param>
        /// <param name="id"></param>
        public static void ReturnInstance(TTransportExt transport, string id)
        {
            if (!_tranPool.TryGetValue(id, out var transpool))
            {
                //可能服务连接池已经被移除
                //transport.Transport.Flush();
                if (transport.Transport.IsOpen)
                {
                    transport.Transport.Close();
                }
                transport.Transport.Dispose();
                transpool.InterlockedDecrement();
                return;
                //throw new ArgumentException("Connection Pool Exception");
            }

            if (transpool.TransportPool.Count > transpool.ServiceConfig.MaxIdle || !transport.Transport.IsOpen)//已经断开的连接直接释放
            {
                //Console.WriteLine($"DisposeTransport--{transpool.TransportPool.Count}");
                //transport.Transport.Flush();
                if (transport.Transport.IsOpen)
                {
                    transport.Transport.Close();
                }
                transport.Transport.Dispose();
            }
            else
            {
                transport.LastDateTime = DateTime.Now; //记录最后访问时间
                transpool.TransportPool.Push(transport);
            }
            transpool.InterlockedDecrement();
            transpool.ResetEvent.Set();
        }
Beispiel #2
0
 /// <summary>
 /// 初始化连接池
 /// </summary>
 public void InitTransportPool()
 {
     if (ServiceConfig != null && TransportPool != null && TransportPool.Count <= 0)
     {
         Task.Factory.StartNew(() =>
         {
             for (int i = 0; i < ServiceConfig.MinIdle; i++)
             {
                 try
                 {
                     var transport = new TSocket(ServiceConfig.Ip, ServiceConfig.Port, ServiceConfig.Timeout);
                     var tExt      = new TTransportExt()
                     {
                         Transport = transport
                         ,
                         Client = new BrokerService.Client(new Thrift.Protocol.TBinaryProtocol(transport))
                         ,
                         LastDateTime = DateTime.Now
                     };
                     transport.Open();
                     TransportPool.Push(tExt);
                 }
                 catch {}
             }
         });
     }
     else
     {
         new ThriftException(ExceptionType.InitTransportPool, $"Please initialize ServiceConfig before calling InitTransportPool");
     }
 }
Beispiel #3
0
        /// <summary>
        /// 处理器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Invoke(Dictionary <string, string> input)
        {
            string output;
            //失败计数器 N次 就直接返回异常
            int error = 0;

reStart:
            try
            {
                BrokerRequest brokerRequest = new BrokerRequest();
                brokerRequest.Input.Add(input);
                output = transport.Client.broker(request: brokerRequest, options: transport.TimeOut.GetCallOptions()).Reply; //如果连接不可用,会报IO异常(重试)
            }
            catch (Exception ex)
            {
                if (ex is RpcException)//连接不可用的时候 直接销毁 从新从连接池拿
                {
                    var sEx = (RpcException)ex;
                    if (sEx.StatusCode == StatusCode.Unavailable || sEx.StatusCode == StatusCode.Aborted)
                    {
                        error++;
                        if (error == 100) //累计3 拿不到有效连接 抛出异常 移除(此值 只是一个参考)
                        {
                            GrpcFactory.RemoveServicePool(id);
                            throw sEx;
                        }

                        GrpcFactory.ReturnInstance(transport, id); //归还有问题链接

                        transport = GrpcFactory.BorrowInstance(id);
                        goto reStart;
                    }
                    else if (sEx.StatusCode == StatusCode.DeadlineExceeded)
                    {
                        GrpcFactory.ReturnInstance(transport, id); //归还有问题链接
                    }
                }
                throw ex;
            }
            return(output);
        }
Beispiel #4
0
 /// <summary>
 /// 归还连接池
 /// </summary>
 /// <param name="transport"></param>
 /// <param name="id"></param>
 public static void ReturnInstance(TTransportExt transport, string id)
 {
     if (!_tranPool.TryGetValue(id, out var transpool))
     {
         transport.Channel.ShutdownAsync();
         //可能服务连接池已经被移除
         return;
     }
     if (transpool.TransportPool.Count >= transpool.ServiceConfig.MaxIdle ||
         transport.Channel.State == ChannelState.Shutdown ||
         transport.Channel.State == ChannelState.TransientFailure)   //已经断开的连接直接释放
     {
         transport.Channel.ShutdownAsync();
     }
     else
     {
         transport.LastDateTime = DateTime.Now; //记录最后访问时间
         transpool.TransportPool.Push(transport);
     }
     transpool.InterlockedDecrement();
     transpool.ResetEvent.Set();
 }
Beispiel #5
0
        /// <summary>
        /// 处理器
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Invoke(Dictionary <string, string> input)
        {
            string output;
            //失败计数器 N次 就直接返回异常
            int error = 0;

reStart:
            try
            {
                if (!transport.Transport.IsOpen)
                {
                    transport.Transport.Open();
                }

                output = transport.Client.broker(input); //如果连接不可用,会报IO异常(重试)
            }
            //catch (TTransportException)
            //{
            //    /*
            //     * 连接打开出错
            //     */
            //    ThriftFactory.RemoveServicePool(id);
            //    throw;
            //}
            catch (AggregateException)
            {
                ThriftFactory.RemoveServicePool(id);
                throw;
            }
            catch (Exception ex)
            {
                if (ex is IOException)//连接不可用的时候 直接销毁 从新从连接池拿
                {
                    var sEx = (SocketException)ex.InnerException;
                    if (sEx?.SocketErrorCode == SocketError.TimedOut)
                    {
                        if (transport.Transport.IsOpen)
                        {
                            transport.Transport.Close();
                        }
                        return(Connector.FailMessage(SocketError.TimedOut.ToString()));
                    }
                    if (sEx?.SocketErrorCode == SocketError.ConnectionReset || sEx?.SocketErrorCode == SocketError.Shutdown)
                    {
                        if (error == 100) //消耗完 线程池里面的 失效连接(此值 只是一个参考)
                        {
                            return(Connector.FailMessage(ex.Message));
                        }

                        if (transport.Transport.IsOpen)
                        {
                            transport.Transport.Close();
                        }
                        ThriftFactory.ReturnInstance(transport, id); //归还有问题链接

                        transport = ThriftFactory.BorrowInstance(id);
                        error++;
                        goto reStart;
                    }
                }
                output = Connector.FailMessage(ex.Message);
            }
            return(output);
        }
Beispiel #6
0
 public Request(string host, int port)
 {
     this.id   = $"{host}:{port}";
     disposed  = false;
     transport = ThriftFactory.BorrowInstance(id);
 }
Beispiel #7
0
        /// <summary>
        /// 定时清理空闲链接
        /// </summary>
        /// <returns></returns>
        internal static void CleanPoolLink()
        {
            try
            {
                List <TTransportExt> invalidLink = new List <TTransportExt>();  //无效连接
                var nowDiff = DateTime.Now - Timespan;
                _tranPool.AsParallel().ForAll(_ =>
                {
                    var pool = _.Value;
                    //只有当 空闲线程存在 30秒没用的空闲连接 才做清理 。防止影响正在运行的 线程
                    if (pool.TransportPool.Count > pool.ServiceConfig.MaxIdle && pool.TransportPool.ToList().Exists(t => t.LastDateTime < nowDiff))
                    {
                        if (pool.TransportPool.ToList().Exists(t => t.LastDateTime < nowDiff))
                        {
                            var transportExts = new ConcurrentStack <TTransportExt>();

                            //有效连接
                            var validLink = pool.TransportPool.Where(t => t.LastDateTime >= nowDiff).ToList();
                            //无效连接
                            invalidLink.AddRange(pool.TransportPool.Where(t => t.LastDateTime < nowDiff).ToList());
                            transportExts.PushRange(validLink.ToArray());

                            pool.TransportPool = transportExts;
                        }
                    }

                    if (pool.TransportPool.Count < pool.ServiceConfig.MinIdle)
                    {
                        int numDiff = pool.ServiceConfig.MinIdle - pool.TransportPool.Count;
                        for (int i = 0; i < numDiff; i++)
                        {
                            try
                            {
                                var transport = new TSocket(pool.ServiceConfig.Ip, pool.ServiceConfig.Port, pool.ServiceConfig.Timeout);
                                var tExt      = new TTransportExt()
                                {
                                    Transport = transport
                                    ,
                                    Client = new BrokerService.Client(new Thrift.Protocol.TBinaryProtocol(transport))
                                    ,
                                    LastDateTime = DateTime.Now
                                };
                                transport.Open();
                                pool.TransportPool.Push(tExt);
                            }
                            catch {}
                        }
                    }
                });
                if (invalidLink.Count > 0)
                {
                    foreach (var invalid in invalidLink)
                    {
                        try
                        {
                            if (invalid.Transport.IsOpen)
                            {
                                invalid.Transport.Flush();
                                invalid.Transport.Close();
                            }
                            invalid.Client.InputProtocol.Dispose();
                            invalid.Client.OutputProtocol.Dispose();
                            invalid.Transport.Dispose();
                        }
                        catch
                        {
                            //回收连接池
                        }
                    }
                }
            }
            catch
            {
                //回收连接池
            }
        }