/// <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(); }
/// <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"); } }
/// <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); }
/// <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(); }
/// <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); }
public Request(string host, int port) { this.id = $"{host}:{port}"; disposed = false; transport = ThriftFactory.BorrowInstance(id); }
/// <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 { //回收连接池 } }