如何尝试捕获对离线 RPC 服务器的 RPC 调用?

Posted

技术标签:

【中文标题】如何尝试捕获对离线 RPC 服务器的 RPC 调用?【英文标题】:How to try-catch a RPC call to an offline RPC server? 【发布时间】:2017-08-21 16:02:12 【问题描述】:

如果我们对在线但不运行 RPC 服务器的服务器进行 RPC 调用,我正在寻找如何继续。

我在我的代码中唯一要做的就是 ping 我们的故障转移 IP 地址以检查服务器是否正在运行,但如果我使用我的 C# 应用程序进行 RPC 调用,它就会崩溃。

RPC 调用函数:

public string Call(string message)

    var corrId = Guid.NewGuid().ToString();
    var props = channel.CreateBasicProperties();
    props.ReplyTo = replyQueueName;
    props.CorrelationId = corrId;

    var messageBytes = Encoding.UTF8.GetBytes(message);
    channel.BasicPublish(exchange: "", routingKey: "rpc_queue", basicProperties: props, body: messageBytes);

    while(true)
    
        var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue();
        if(ea.BasicProperties.CorrelationId == corrId)
        
            return Encoding.UTF8.GetString(ea.Body);
        
    

有人有解决办法吗?

PS:RabbitMQ 承认没有解决以下问题:

我们的代码仍然非常简单,并没有尝试解决更复杂(但重要)的问题,例如:

如果没有服务器在运行,客户端应该如何反应?

客户端是否应该为 RPC 设置某种超时?

谢谢。

【问题讨论】:

你读过 Paxos 容错算法吗?如果没有,请通过它。 对不起...已编辑!我读过 Paxos,但它看起来很复杂 :) 【参考方案1】:

对于那些有这个问题的人,我解决了这个问题:

try

    var task = Task.Run(() => rpcClient.Call(data_encoded));
    if (task.Wait(TimeSpan.FromSeconds(3)))
    
        response = task.Result;
    
    else
    
        throw new Exception("Timed out");
    
    Console.WriteLine("RESPONSE : " + response);

catch (Exception e)

    // Some code here ...

【讨论】:

【参考方案2】:

我是 RabbitMQ 和 RPC 的新手,但在从我的客户端发出 RPC 调用之前,我使用以下检查来查看服务器是否处于活动状态:

private bool IsRpcServerAlive()

   // create a temporary channel since it will not be
   // reusable if an exception is thrown
   using (var tempChannel = connection.CreateModel())
   
      try
      
         // throws an exception if the Queue does not exist
         var declareResult = channel.QueueDeclarePassive("rpc_queue");
         // RPC server is the only consumer of the Queue
         return declareResult.ConsumerCount > 0;
      
      catch (RabbitMQ.Client.Exceptions.OperationInterruptedException)
      
         return false;
      
   

这对我有用,因为我的服务器是队列的唯一消费者。有关被动声明的更多信息,请参阅https://www.rabbitmq.com/dotnet-api-guide.html#passive-declaration

【讨论】:

以上是关于如何尝试捕获对离线 RPC 服务器的 RPC 调用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 GWT RPC 中将异常从服务器传递到客户端

跟踪 Corda 中的状态变化

如何从另一个 rpc 服务调用 rpc 服务方法?

如何理解 RPC 远程服务调用?

RPC服务 RPC相关概念详解,以及如何设计一个RPC框架

rpc服务器不可用 如何修复Windows上的RPC服务器不可用错误