如何尝试捕获对离线 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 调用?的主要内容,如果未能解决你的问题,请参考以下文章