예제 #1
0
        public object Resolve(Type type)
        {
            IService service = ServiceFinder.Find(Storage.Services, type);

            if (service == null)
            {
                throw new ResolveException(type);
            }

            object result = ServiceInstanceResolver.ResolveInstance(service, this);

            return(result);
        }
예제 #2
0
파일: ClientProxy.cs 프로젝트: lulzzz/spear
        private async Task <ResultMessage> BaseInvoke(MethodInfo targetMethod, object[] args)
        {
            var            services      = (await _serviceFinder.Find(targetMethod.DeclaringType) ?? new List <ServiceAddress>()).ToList();
            var            invokeMessage = Create(targetMethod, args);
            ServiceAddress service       = null;
            var            builder       = Policy
                                           .Handle <Exception>(ex => ex.GetBaseException() is SocketException) //服务器异常
                                           .OrResult <ResultMessage>(r => r.Code != 200);                      //服务未找到
            //熔断,3次异常,熔断5分钟
            var breaker = builder.CircuitBreakerAsync(3, TimeSpan.FromMinutes(5));
            //重试3次
            var retry = builder.RetryAsync(3, (result, count) =>
            {
                _logger.Warn(result.Exception != null
                    ? $"{service}{targetMethod.Name}:retry,{count},{result.Exception.Format()}"
                    : $"{service}{targetMethod.Name}:retry,{count},{result.Result.Code}");
                services.Remove(service);
            });

            var policy = Policy.WrapAsync(retry, breaker);

            return(await policy.ExecuteAsync(async() =>
            {
                if (!services.Any())
                {
                    throw ErrorCodes.NoService.CodeException();
                }

                service = services.RandomSort().First();

                return await InvokeAsync(service.ToEndPoint(), invokeMessage);
            }));
        }
예제 #3
0
        protected override object Resolve(Type type, object key = null)
        {
            if (typeof(ClientBase).IsAssignableFrom(type))
            {
                //find service
                var services = _finder.Find(type).ConfigureAwait(false).GetAwaiter().GetResult();
                if (services == null || !services.Any())
                {
                    throw ErrorCodes.NoService.CodeException();
                }
                var service = services.Random();
                if (service.Protocol != ServiceProtocol.Grpc)
                {
                    return(null);
                }
                var channel = GrpcChannel.ForAddress($"http://{service.Service}:{service.Port}", new GrpcChannelOptions
                {
                    Credentials = ChannelCredentials.Insecure
                });

                var client = Activator.CreateInstance(type, channel);
                return(client);
            }
            return(null);
        }
예제 #4
0
        public string Invoke(string apiCode, string body)
        {
            var        api     = _apiFinder.Find(apiCode);
            var        service = _serviceFinder.Find(api.ServiceId);
            ApiContext context = new ApiContext
            {
                ApiDescription     = api,
                ServiceDescription = service,
                Body = body
            };

            return(_httpInvoker.Invoke(context.RequestUrl, body));
        }
예제 #5
0
        private async Task <MessageResult> InternalInvoke(MethodInfo targetMethod, IDictionary <string, object> args)
        {
            var serviceType = targetMethod.DeclaringType;

            var services = (await _serviceFinder.Find(serviceType) ?? new List <ServiceAddress>())
                           .ToList();

            if (!services.Any())
            {
                throw ErrorCodes.NoService.CodeException();
            }
            var            invokeMessage = Create(targetMethod, args);
            ServiceAddress service       = null;
            var            builder       = Policy
                                           .Handle <Exception>(ex =>
                                                               ex.GetBaseException() is SocketException ||
                                                               ex.GetBaseException() is HttpRequestException ||
                                                               (ex.GetBaseException() is SpearException spearEx && spearEx.Code == ErrorCodes.SystemError)) //服务器异常
                                           .OrResult <MessageResult>(r => r.Code != 200);                                                                   //服务未找到

            //熔断,3次异常,熔断5分钟
            var breaker = builder.CircuitBreakerAsync(3, TimeSpan.FromMinutes(5));
            //重试3次
            var retry = builder.RetryAsync(3, (result, count) =>
            {
                _logger.LogWarning(result.Exception != null
                    ? $"{service}{targetMethod.Name}:retry,{count},{result.Exception.Format()}"
                    : $"{service}{targetMethod.Name}:retry,{count},{result.Result.Code}");
                services.Remove(service);
                _serviceFinder.CleanCache(serviceType);
            });

            var policy = Policy.WrapAsync(retry, breaker);

            return(await policy.ExecuteAsync(async() =>
            {
                if (!services.Any())
                {
                    await _serviceFinder.CleanCache(serviceType);
                    throw ErrorCodes.NoService.CodeException();
                }

                service = services.Random();

                return await ClientInvokeAsync(service, invokeMessage);
            }));
        }
예제 #6
0
 public void Start(ServiceConfig serviceConfig)
 {
     IServiceAssembliesResolver assembliesResolver = GlobalSetting.Container.GetService<IServiceAssembliesResolver>();
     if (assembliesResolver == null)
         throw new NullReferenceException("IServiceAssembliesResolver接口不能为空");
     IServiceFinder serviceFinder = GlobalSetting.Container.GetService<IServiceFinder>();
     if (serviceFinder == null)
         throw new NullReferenceException("IServiceFinder接口不能为空");
     IEnumerable<ServiceMap> serviceMaps = FilterServiceMap(serviceFinder.Find(assembliesResolver.GetAssemblies()), serviceConfig.Server.Services);
     IServiceDiscoverer serviceDiscoverer = GlobalSetting.Container.GetService<IServiceDiscoverer>();
     if (serviceDiscoverer == null)
         throw new NullReferenceException("IServiceDiscoverer接口不能为空");
     serviceDiscoverer.RegistrationCenter = serviceConfig.RegistrationCenter;
     IEnumerable<Service> servics = FilterServices(serviceDiscoverer.Discover(serviceMaps), serviceConfig.Client.Services);
     IThriftClientActivator thriftClientActivator = GlobalSetting.Container.GetService<IThriftClientActivator>();
     if (thriftClientActivator == null)
         throw new NullReferenceException("IThriftClientActivator接口不能为空");
     thriftClientActivator.RegisterServices(servics);
 }
예제 #7
0
 public bool Check(IServiceList list, Type type)
 {
     return(Finder.Find(list, type) != null);
 }