Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="call"></param>
        /// <param name="retryLeft"></param>
        /// <returns></returns>
        private TResponse Call <TResponse>(Func <CallInvoker, TResponse> call, int retryLeft)
        {
            while (true)
            {
                var callInvoker = default(ServerCallInvoker);
                try
                {
                    if (_callInvokers != null)
                    {
                        var invokers = _strategy.GetCallInvokers(_options.ServiceName);
                        callInvoker = _callInvokers(invokers);
                    }
                    else
                    {
                        callInvoker = _strategy.GetCallInvoker(_options.ServiceName);
                    }


                    if (callInvoker == null)
                    {
                        throw new ArgumentNullException($"{_options.ServiceName}无可用节点");
                    }
                    if (callInvoker.Channel == null || callInvoker.Channel.State == ChannelState.TransientFailure)
                    {
                        throw new RpcException(new Status(StatusCode.Unavailable, $"Channel Failure"));
                    }

                    if (_options.Interceptors?.Count > 0)
                    {
                        return(call(callInvoker.Intercept(_options.Interceptors.ToArray())));
                    }
                    return(call(callInvoker));
                }
                catch (RpcException ex)
                {
                    // 服务不可用,拉入黑名单
                    if (ex.Status.StatusCode == StatusCode.Unavailable)
                    {
                        _strategy.Revoke(_options.ServiceName, callInvoker);
                    }

                    if (0 > --retryLeft)
                    {
                        throw new Exception($"status: {ex.StatusCode}, node: {callInvoker?.Channel?.Target}, message: {ex.Message}", ex);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="call"></param>
        /// <param name="retryLeft"></param>
        /// <returns></returns>
        private TResponse Call <TResponse>(Func <CallInvoker, TResponse> call, int retryLeft)
        {
            while (true)
            {
                var callInvoker = default(ServerCallInvoker);
                try
                {
                    callInvoker = _strategy.Get(_serviceName);
                    if (callInvoker == null)
                    {
                        throw new ArgumentNullException($"{_serviceName}无可用节点");
                    }

                    var channel = callInvoker.Channel;
                    if (channel == null || channel.State == ChannelState.TransientFailure)
                    {
                        throw new RpcException(new Status(StatusCode.Unavailable, $"Channel Failure"));
                    }

                    var response = default(TResponse);
                    if (_tracer != null)
                    {
                        response = call(callInvoker.ClientIntercept(_tracer));
                    }
                    else
                    {
                        response = call(callInvoker);
                    }
                    return(response);
                }
                catch (RpcException ex)
                {
                    // 服务不可用,拉入黑名单
                    if (ex.Status.StatusCode == StatusCode.Unavailable)
                    {
                        _strategy.Revoke(_serviceName, callInvoker);
                    }

                    if (0 > --retryLeft)
                    {
                        throw new Exception($"status: {ex.StatusCode.ToString()}, node: {callInvoker?.Channel?.Target}, message: {ex.Message}", ex);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="TResponse"></typeparam>
        /// <param name="call"></param>
        /// <param name="retryLeft"></param>
        /// <returns></returns>
        private TResponse Call <TResponse>(Func <CallInvoker, TResponse> call, int retryLeft)
        {
            while (true)
            {
                var callInvoker = default(ServerCallInvoker);
                try
                {
                    callInvoker = _strategy.Get(_serviceName);
                    if (callInvoker == null)
                    {
                        throw new ArgumentNullException("无任何可用连接");
                    }

                    var channel = callInvoker.Channel;
                    if (channel == null || channel.State == ChannelState.TransientFailure)
                    {
                        throw new RpcException(new Status(StatusCode.Unavailable, "Channel Failure"));
                    }

                    var response = default(TResponse);
                    if (_tracer != null)
                    {
                        response = call(callInvoker.ClientIntercept(_tracer));
                    }
                    else
                    {
                        response = call(callInvoker);
                    }
                    return(response);
                }
                catch (RpcException ex)
                {
                    if (ex.Status.StatusCode == StatusCode.Unavailable)
                    {
                        _strategy.Revoke(_serviceName, callInvoker);
                    }

                    if (0 > --retryLeft)
                    {
                        throw;
                    }
                }
            }
        }
Ejemplo n.º 4
0
        private TResponse Call <TResponse>(string serviceName, Func <CallInvoker, TResponse> call, int retryLeft)
        {
            while (true)
            {
                var callInvoker = _endpointStrategy.Get(serviceName);
                try
                {
                    return(call(callInvoker));
                }
                catch (RpcException ex)
                {
                    // forget channel if unavailable
                    if (ex.Status.StatusCode == StatusCode.Unavailable)
                    {
                        _endpointStrategy.Revoke(serviceName, callInvoker);
                    }

                    if (0 > --retryLeft)
                    {
                        throw;
                    }
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 核心执行
        /// </summary>
        private void DoRun()
        {
            try
            {
                //这里做兼容,从不同地址获取配置信息
                List <GrpcService> listServ = null;
#if NETCORE
                IOptionsMonitor <List <GrpcService> > grpcServices = _serviceProvider.GetRequiredService <IOptionsMonitor <List <GrpcService> > >();
                listServ = grpcServices.CurrentValue;
#else
                listServ = GrpcServiceWrapper.Services;
#endif
                if (listServ == null || !listServ.Any())
                {
                    _serviceDiscovery.CleanTarget();
                    _endpointStrategy.ShutDownAll();
                    return;
                } //如果没有配置,则清理所有

                var haveTargetKeys = _endpointStrategy.Targets;
                var serviceNames   = listServ
                                     .OrderByDescending(s => s.IsDiscovery)
                                     .Select(s => s.ServiceName)
                                     .Where(s => !string.IsNullOrEmpty(s))
                                     .Distinct(); //服务发现优先

                foreach (var serviceName in serviceNames)
                {
                    List <EndpointModel> healthTarget = null;
                    var service       = listServ.Where(s => s.ServiceName == serviceName);
                    var discoveryServ = service.Where(s => s.IsDiscovery).FirstOrDefault();
                    if (discoveryServ != null)
                    {
                        healthTarget = _serviceDiscovery.SaveServiceEndpoint(discoveryServ.ServiceName);
                    } //优先处理 服务发现
                    else
                    {
                        healthTarget = service
                                       .Where(s => !s.IsDiscovery)
                                       .Select(s => new EndpointModel
                        {
                            IsDisconvry = false,
                            Host        = s.Host,
                            Port        = s.Port
                        }).ToList();
                        _serviceDiscovery.SaveFindServiceEndpoint(serviceName, healthTarget);
                    } //如果本机服务存在
                    if (healthTarget == null)
                    {
                        healthTarget = new List <EndpointModel>();
                    }
                    //处理健康地址
                    var oldTargetKeys    = haveTargetKeys.Where(t => _endpointStrategy.IsExistService(t, serviceName)).ToList();
                    var healthTargetKeys = healthTarget.Select(h => _endpointStrategy.GetCallInvokerKey(serviceName, h.ToString())).ToList();

                    //求出不存在的
                    var unHealthTargetKey = oldTargetKeys.Except(healthTargetKeys);

                    _endpointStrategy.Revoke(unHealthTargetKey.ToArray()); //不健康的剔除
                    _endpointStrategy.Create(healthTargetKeys.ToArray());  //健康的创建
                }

                //释放
                haveTargetKeys.Clear();
            }
            catch (Exception ex)
            {
                CommonUtilsHelper._.LoggerWriter.Invoke(string.Format("[客户端守护线程]发生异常 {0}", ex.Message), ex);
            }
        }