Ejemplo n.º 1
0
 public DefaultServiceEntryGenerator(IServiceIdGenerator serviceIdGenerator,
                                     IParameterProvider parameterProvider,
                                     IHttpMethodProvider httpMethodProvider,
                                     IOptions <GovernanceOptions> governanceOptions)
 {
     _serviceIdGenerator = serviceIdGenerator;
     _parameterProvider  = parameterProvider;
     _httpMethodProvider = httpMethodProvider;
     _governanceOptions  = governanceOptions.Value;
 }
Ejemplo n.º 2
0
 private void MarkAddressFail(GovernanceOptions governanceOptions, IAddressModel selectedAddress,
                              bool isTimeoutEx = false)
 {
     if (governanceOptions.FuseProtection)
     {
         selectedAddress.MakeFusing(governanceOptions.FuseSleepDuration);
         if (selectedAddress.FuseTimes > governanceOptions.FuseTimes && !isTimeoutEx)
         {
             _healthCheck.ChangeHealthStatus(selectedAddress, false, governanceOptions.FuseTimes);
         }
     }
     else if (!isTimeoutEx)
     {
         _healthCheck.ChangeHealthStatus(selectedAddress, false);
     }
 }
Ejemplo n.º 3
0
        public ServiceEntry(IRouter router,
                            ServiceDescriptor serviceDescriptor,
                            Type serviceType,
                            MethodInfo methodInfo,
                            IReadOnlyList <ParameterDescriptor> parameterDescriptors,
                            IRouteTemplateProvider routeTemplateProvider,
                            bool isLocal,
                            GovernanceOptions governanceOptions)
        {
            Router                      = router;
            ServiceDescriptor           = serviceDescriptor;
            ParameterDescriptors        = parameterDescriptors;
            _serviceType                = serviceType;
            IsLocal                     = isLocal;
            MultipleServiceKey          = routeTemplateProvider.MultipleServiceKey;
            GroupName                   = serviceType.FullName;
            MethodInfo                  = methodInfo;
            CustomAttributes            = MethodInfo.GetCustomAttributes(true);
            (IsAsyncMethod, ReturnType) = MethodInfo.ReturnTypeInfo();
            GovernanceOptions           = new ServiceEntryGovernance();
            var governanceProvider = CustomAttributes.OfType <IGovernanceProvider>().FirstOrDefault();

            if (governanceProvider != null)
            {
                ReConfiguration(governanceProvider);
            }
            else
            {
                ReConfiguration(governanceOptions);
            }

            _methodExecutor = methodInfo.CreateExecutor(serviceType);
            Executor        = CreateExecutor();
            CreateDefaultSupportedRequestMediaTypes();
            CreateDefaultSupportedResponseMediaTypes();
        }
Ejemplo n.º 4
0
        public async Task <RemoteResultMessage> Invoke(RemoteInvokeMessage remoteInvokeMessage,
                                                       GovernanceOptions governanceOptions, string hashKey = null)
        {
            var serviceRoute = _serviceRouteCache.GetServiceRoute(remoteInvokeMessage.ServiceId);

            if (serviceRoute == null)
            {
                throw new LmsException($"通过{remoteInvokeMessage.ServiceId}找不到服务路由", StatusCode.NotFindServiceRoute);
            }

            if (!serviceRoute.Addresses.Any(p => p.Enabled))
            {
                throw new NotFindServiceRouteAddressException($"通过{remoteInvokeMessage.ServiceId}找不到可用的服务提供者");
            }

            var addressSelector =
                EngineContext.Current.ResolveNamed <IAddressSelector>(governanceOptions.ShuntStrategy.ToString());
            var selectedAddress =
                addressSelector.Select(new AddressSelectContext(remoteInvokeMessage.ServiceId, serviceRoute.Addresses,
                                                                hashKey));
            bool isInvakeSuccess = true;
            var  sp = Stopwatch.StartNew();

            try
            {
                _remoteServiceSupervisor.Monitor((remoteInvokeMessage.ServiceId, selectedAddress),
                                                 governanceOptions);
                var client = await _transportClientFactory.GetClient(selectedAddress);

                //RpcContext.GetContext().SetAttachment("localAddress", NetUtil.GetRpcAddressModel().ToString());
                RpcContext.GetContext().SetAttachment("remoteAddress", selectedAddress.ToString());
                return(await client.SendAsync(remoteInvokeMessage, governanceOptions.ExecutionTimeout));
            }
            catch (IOException ex)
            {
                Logger.LogError($"服务提供者{selectedAddress}不可用,IO异常,原因:{ex.Message}");
                _healthCheck.RemoveAddress(selectedAddress);
                isInvakeSuccess = false;
                throw new CommunicatonException(ex.Message, ex.InnerException);
            }
            catch (ConnectException ex)
            {
                Logger.LogError($"与服务提供者{selectedAddress}链接异常,原因:{ex.Message}");
                MarkAddressFail(governanceOptions, selectedAddress);
                isInvakeSuccess = false;
                throw new CommunicatonException(ex.Message, ex.InnerException);
            }
            catch (ChannelException ex)
            {
                Logger.LogError($"与服务提供者{selectedAddress}通信异常,原因:{ex.Message}");
                MarkAddressFail(governanceOptions, selectedAddress);
                isInvakeSuccess = false;
                throw new CommunicatonException(ex.Message, ex.InnerException);
            }
            catch (TimeoutException ex)
            {
                Logger.LogError($"与服务提供者{selectedAddress}执行超时,原因:{ex.Message}");
                MarkAddressFail(governanceOptions, selectedAddress, true);
                isInvakeSuccess = false;
                throw;
            }
            finally
            {
                sp.Stop();
                if (isInvakeSuccess)
                {
                    _remoteServiceSupervisor.ExecSuccess((remoteInvokeMessage.ServiceId, selectedAddress),
                                                         sp.Elapsed.TotalMilliseconds);
                }
                else
                {
                    _remoteServiceSupervisor.ExceFail((remoteInvokeMessage.ServiceId, selectedAddress),
                                                      sp.Elapsed.TotalMilliseconds);
                }
            }
        }