RabbitMQ 学习笔记(六):RPC

远程过程调用(RPC)

在第二个笔记,我们学习了如何使用工作队列(work queue)在多个 worker 之间分配耗时的任务。

但是,如果我们需要在远程计算机上运行一个函数并等待结果呢?那就是另一回事了。这种模式通常称为远程过程调用(Remote Procedure Call)或简称“RPC”

在本教程中,我们将使用RabbitMQ构建一个RPC系统:一个客户机和一个可伸缩的RPC服务器。由于我们没有任何值得分发的费时任务,我们将创建一个虚拟RPC服务来返回斐波那契数列

客户端接口

为了说明如何使用RPC服务,我们将创建一个简单的客户端类。它将公开一个名为call的方法,该方法会一直发送RPC请求和blocks,直到收到应答为止:

FibonacciRpcClient fibonacciRpc = new FibonacciRpcClient();
String result = fibonacciRpc.call("4");
System.out.println( "fib(4) is " + result);

关于RPC,请注意:

尽管RPC在计算中是一个很常见的模式,但它却经常受到批评。当程序员不知道函数调用是本地的还是一个 slow RPC 时,问题就出现了。这样的混淆可能导致不可预知的系统,并增加了调试的不必要的复杂性。与简化软件不同,错误的RPC可能导致无法维护的意大利面代码。

考虑到这一点,考虑以下建议:
1. 确保函数调用是本地的,而且是远程的
2. 文件化系统。使组件之间的依赖关系变得清晰
3. 处理错误(error)情况。当RPC服务器宕了很长时间时,客户机应该如何反应?

当有疑问时避免使用RPC。如果可以的话,您应该使用异步管道,而不是像 RPC 。像blocking(阻塞)一样,结果会被异步地推到下一个计算阶段。

回调队列(Callback queue)

一般来说,在RabbitMQ上执行RPC是很容易的。一个客户端发送一个请求消息,一个服务器回复一个响应消息。为了收到响应,我们需要发送一个callback queue地址。我们可以使用默认队列(在Java客户机中是独占的)。让我们试一试:

callbackQueueName = channel.queueDeclare().getQueue();

BasicProperties props = new BasicProperties
                            .Builder()
                            .replyTo(callbackQueueName)
                            .build();

channel.basicPublish("", "rpc_queue", props, message.getBytes());

// ... 然后代码从callback_queue读取响应消息 ...

消息属性

1.deliveryMode(交付模式):将消息标记为持久(具有值为2)或暂态(任何其他值)。您可能还记得第二个笔记中的这个属性。
2. contentType:用于描述编码的mime类型。例如,对于经常使用的JSON编码,将该属性设置为: application/json 是一种很好的做法。
3.replyTo:通常用于callback_queue。
4.correlationship:用于将RPC响应与请求关联起来。

我们需要一个新的 import:

import com.rabbitmq.client.AMQP.BasicProperties;

Correlation Id(关联ID)

在上述方法中,我们假定为每个RPC请求创建回调队列。这是非常低效的,但是幸运的是,我们有有更好的方法——为每个客户机创建一个回调队列

这引发了一个新问题,在该队列中收到了响应,但不清楚响应属于哪个请求。这就是使用 correlation id 属性的时候。我们将把它设置为每个请求的唯一值。稍后,当我们在callback queue中接收消息时,我们将查看此属性,基于此,我们将能够匹配响应和请求。如果我们看到一个未知的关联值,我们可以安全地丢弃这个消息——它不属于我们的请求

您可能会问,为什么我们应该忽略回调队列中的未知消息,而不是返回一个 error 然后结束?这是由于服务器端可能出现竞态条件(race condition)。尽管不太可能,但RPC服务器可能在发送答案后才会死亡,但这将在发送确认消息(ack)之前。如果发生这种情况,重新启动的RPC服务器将再次处理请求。这就是为什么在客户端我们必须优雅地处理重复的响应,并且RPC应该是具有幂等性的。

Summary

我们的RPC将这样工作:

当客户机启动时,它创建一个匿名的独有的 callback_queue

对于RPC请求,客户端发送带有两个属性的消息:一. replyTo,它被设置为callback_queue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值