【问题标题】:How to try-catch a RPC call to an offline RPC server?如何尝试捕获对离线 RPC 服务器的 RPC 调用?
【发布时间】: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,但它看起来很复杂 :)

标签: c# .net rabbitmq rpc


【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 2010-12-07
      • 2017-11-24
      • 2023-04-08
      • 2011-01-24
      • 1970-01-01
      相关资源
      最近更新 更多