public async Task InvokeAsync(RemoteInvokeContext context, CancellationToken cancellationToken)
        {
            var mqttContext = context as MqttRemoteInvokeContext;

            if (mqttContext != null)
            {
                var invokeMessage = context.InvokeMessage;
                var host          = NetUtils.GetHostAddress();
                var addresses     = await _mqttBrokerEntryManger.GetMqttBrokerAddress(mqttContext.topic);

                addresses = addresses.Except(new AddressModel[] { host });
                foreach (var address in addresses)
                {
                    try
                    {
                        var endPoint = address.CreateEndPoint();
                        if (_logger.IsEnabled(LogLevel.Debug))
                        {
                            _logger.LogDebug($"使用地址:'{endPoint}'进行调用。");
                        }
                        var client = _transportClientFactory.CreateClient(endPoint);
                        await client.SendAsync(invokeMessage).WithCancellation(cancellationToken);
                    }
                    catch (CommunicationException)
                    {
                        await _healthCheckService.MarkFailure(address);
                    }
                    catch (Exception exception)
                    {
                        _logger.LogError(exception, $"发起请求中发生了错误,服务Id:{invokeMessage.ServiceId}。");
                    }
                }
            }
        }
Example #2
0
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context, CancellationToken cancellationToken)
        {
            var          invokeMessage = context.InvokeMessage;
            AddressModel address       = null;
            var          vt            = ResolverAddress(context, context.Item);

            address = vt.IsCompletedSuccessfully? vt.Result: await vt;
            try
            {
                var endPoint = address.CreateEndPoint();
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"使用地址:'{endPoint}'进行调用。");
                }
                var client = _transportClientFactory.CreateClient(endPoint);
                return(await client.SendAsync(invokeMessage, cancellationToken).WithCancellation(cancellationToken));
            }
            catch (CommunicationException)
            {
                await _healthCheckService.MarkFailure(address);

                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, $"发起请求中发生了错误,服务Id:{invokeMessage.ServiceId}。");
                throw;
            }
        }
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context, CancellationToken cancellationToken)
        {
            var          invokeMessage = context.InvokeMessage;
            AddressModel address       = null;

            try
            {
                address = await ResolverAddress(context, context.Item);

                var endPoint = address.CreateEndPoint();
                if (_logger.IsEnabled(LogLevel.Information))
                {
                    _logger.LogInformation($"使用地址:'{endPoint}'进行调用。");
                }
                var client = await _transportClientFactory.CreateClientAsync(endPoint);

                RpcContext.GetContext().SetAttachment("RemoteAddress", address.ToString());
                var rpcResult = await client.SendAsync(invokeMessage, cancellationToken).WithCancellation(cancellationToken);

                return(rpcResult);
            }
            catch (CommunicationException ex)
            {
                if (address != null)
                {
                    _logger.LogError($"使用地址:'{address.ToString()}'调用服务{context.InvokeMessage.ServiceId}通信错误,原因:{ex.Message}");
                }
                if (address != null)
                {
                    await _healthCheckService.MarkFailure(address);
                }
                throw;
            }
            catch (TimeoutException ex)
            {
                if (address != null)
                {
                    _logger.LogError($"使用地址:'{address.ToString()}'调用服务{context.InvokeMessage.ServiceId}超时,原因:{ex.Message}");
                }
                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError(exception, $"发起请求中发生了错误,服务Id:{invokeMessage.ServiceId}。");

                throw;
            }
        }
 private async Task MarkServiceUnHealth(IChannelHandlerContext context)
 {
     var iPEndPoint     = context.Channel.RemoteAddress as IPEndPoint;
     var ipAddressModel = new IpAddressModel(iPEndPoint.Address.MapToIPv4().ToString(),
                                             iPEndPoint.Port);
     await _healthCheckService.MarkFailure(ipAddressModel);
 }
 private IRpcClient GetOrAdd(EndPoint endPoint)
 {
     try
     {
         return(_clients.GetOrAdd(endPoint, ep =>
         {
             return new Lazy <IRpcClient>(() =>
             {
                 var clientService = new DotNettyClientService();
                 var bootstrap = _bootstrap;
                 var channel = bootstrap.ConnectAsync(ep).Result;
                 channel.GetAttribute(origEndPointKey).Set(ep);
                 channel.GetAttribute(_clientServiceAttributeKey).Set(clientService);
                 return new DotNettyClient(channel, clientService);
             });
         }).Value);
     }
     catch (Exception e)
     {
         _clients.TryRemove(endPoint, out var value);
         var ipEndPoint = endPoint as IPEndPoint;
         if (ipEndPoint != null)
         {
             _healthCheckService.MarkFailure(new IpAddressModel(ipEndPoint.Address.ToString(), ipEndPoint.Port));
         }
         throw new RpcConnectedException("与服务端连接时发生异常。", e);
     }
 }
            private async Task MarkServiceUnHealth(IChannelHandlerContext context)
            {
                var providerServerEndpoint = context.Channel.RemoteAddress as IPEndPoint;
                var providerServerAddress  = new IpAddressModel(providerServerEndpoint.Address.MapToIPv4().ToString(),
                                                                providerServerEndpoint.Port);

                _factory.RemoveClient(providerServerEndpoint);
                _factory.RemoveClient(context.Channel.GetAttribute(origEndPointKey).Get());
                await _healthCheckService.MarkFailure(providerServerAddress);
            }
Example #7
0
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.ServiceId == null)
            {
                throw new ArgumentNullException("serviceId");
            }

            RemoteInvokeMessage message = new RemoteInvokeMessage()
            {
                ServiceId  = context.ServiceId,
                Parameters = context.Parameters
            };
            var transportMessage = TransportMessage.CreateInvokeMessage(message);


            var retryPolicy = Policy.Handle <RpcConnectedException>()
                              .Or <RpcRemoteException>()
                              .WaitAndRetryAsync(5, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt))
                                                 , async(ex, time, i, ctx) =>
            {
                var address = ctx["address"] as AddressModel;
                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"第{i}次重试,重试时间间隔{time.Seconds},发生时间:{DateTime.Now},地址:{address.ToString()}");
                }
                await _healthCheckService.MarkFailure(address);
            });


            #region MyRegion
            //var fallBackPolicy = Policy<TransportMessage>.Handle<Exception>().Fallback(new TransportMessage());
            //var mixPolicy = Policy.Wrap(fallBackPolicy, retryPolicy);
            //var breakerPolicy=Policy.Handle<RpcConnectedException>()
            //                    .CircuitBreakerAsync(5,TimeSpan.FromSeconds(10),)
            #endregion

            try
            {
                var policyContext = new Context();
                return(await retryPolicy.ExecuteAsync <RemoteInvokeResultMessage>(ctx =>
                {
                    return RetryExectueAsync(ctx, _addressResolver, context.ServiceId, transportMessage);
                }, policyContext));
            }
            catch (Exception e)
            {
                //await _healthCheckService.MarkFailure(address);
                _logger.LogError("发送远程消息错误", e);
                throw e;
            }
        }
Example #8
0
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context,
                                                                  CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.InvokeMessage == null)
            {
                throw new ArgumentNullException(nameof(context.InvokeMessage));
            }

            if (string.IsNullOrEmpty(context.InvokeMessage.ServiceId))
            {
                throw new ArgumentException("服务Id不能为空", nameof(context.InvokeMessage.ServiceId));
            }

            var invokeMessage = context.InvokeMessage;
            var address       = await _addressResolver.Resolver(invokeMessage.ServiceId);

            if (address == null)
            {
                throw new RpcException($"无法解析服务Id:{invokeMessage.ServiceId}的地址信息");
            }

            try
            {
                var endPoint = address.CreateEndPoint();

                if (_logger.IsEnabled(LogLevel.Debug))
                {
                    _logger.LogDebug($"使用地址:'{endPoint}'进行调用");
                }

                var client = _transportClientFactory.CreateClient(endPoint);
                return(await client.SendAsync(context.InvokeMessage));
            }
            catch (RpcCommunicationException)
            {
                await _healthCheckService.MarkFailure(address);

                throw;
            }
            catch (Exception exception)
            {
                _logger.LogError($"发起请求中发生了错误,服务Id:{invokeMessage.ServiceId}", exception);
                throw;
            }
        }
Example #9
0
        public async Task InvokeAsync(RemoteInvokeMessage message, int requestTimeout)
        {
            var          host    = NetUtils.GetHostAddress();
            AddressModel address = host;
            var          route   = await _serviceRotueProvider.GetRouteByPath(_routePath);

            if (route != null && route.Address.Count() > 1)
            {
                try
                {
                    var addresses = route.Address.ToList();
                    var index     = addresses.IndexOf(host);
                    for (var i = 1; i < AppConfig.Option.ClusterNode; i++)
                    {
                        ++index;
                        if (addresses.Count == index)
                        {
                            index = 0;
                        }
                        address = addresses[index];
                        if (host == address)
                        {
                            break;
                        }
                        var endPoint = address.CreateEndPoint();
                        if (_logger.IsEnabled(LogLevel.Debug))
                        {
                            _logger.LogDebug($"使用地址:'{endPoint}'进行调用。");
                        }
                        var client = await _transportClientFactory.CreateClientAsync(endPoint);

                        using (var cts = new CancellationTokenSource())
                        {
                            await client.SendAsync(message, cts.Token).WithCancellation(cts, requestTimeout);
                        }
                    }
                }
                catch (CommunicationException ex)
                {
                    await _healthCheckService.MarkFailure(address);
                }
                catch (Exception exception)
                {
                    _logger.LogError(exception, $"发起live请求中发生了错误,服务Id:{message.ServiceId}。");
                }
            }
        }
        public async Task <ITransportClient> CreateClientAsync(EndPoint endPoint)
        {
            var key = endPoint;

            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug($"准备为服务端地址:{key}创建客户端。");
            }
            try
            {
                return(await _clients.GetOrAdd(key
                                               , k => new Lazy <Task <ITransportClient> >(async() =>
                {
                    var ipEndPoint = k as IPEndPoint;
                    var transport = new TSocketTransport(ipEndPoint.Address.ToString(), ipEndPoint.Port);
                    var tran = new TFramedTransport(transport);
                    var protocol = new TBinaryProtocol(tran);
                    var mp = new TMultiplexedProtocol(protocol, "thrift.surging");
                    var messageListener = new MessageListener();
                    var messageSender = new ThriftMessageClientSender(_transportMessageEncoder, protocol);
                    var result = new TThriftClient(protocol, messageSender, messageListener, new ChannelHandler(_transportMessageDecoder, messageListener, messageSender, _logger), _logger);
                    await result.OpenTransportAsync();
                    return result;
                }
                                                                                          )).Value);//返回实例
            }
            catch (Exception ex)
            {
                //移除
                _clients.TryRemove(key, out var value);
                var ipEndPoint = endPoint as IPEndPoint;
                //标记这个地址是失败的请求
                if (ipEndPoint != null)
                {
                    await _healthCheckService.MarkFailure(new IpAddressModel(ipEndPoint.Address.ToString(), ipEndPoint.Port));
                }
                throw;
            }
        }
        public async Task <RemoteInvokeResultMessage> InvokeAsync(RemoteInvokeContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (context.ServiceId == null)
            {
                throw new ArgumentNullException("serviceId");
            }

            RemoteInvokeMessage message = new RemoteInvokeMessage()
            {
                ServiceId  = context.ServiceId,
                Parameters = context.Parameters
            };
            var transportMessage = TransportMessage.CreateInvokeMessage(message);

            //todo: 添加断路器(polly)

            var address = await _addressResolver.ResolverAsync(context.ServiceId);

            var client = _clientFactory.CreateClientAsync(address.CreateEndPoint());

            try
            {
                return(await client.SendAsync(transportMessage));
            }
            catch (Exception e)
            {
                await _healthCheckService.MarkFailure(address);

                _logger.LogError("发送远程消息错误", e);
                throw e;
            }
        }