如果我们需要在远程计算机上运行一个函数并等待结果,这种模式通常被称为远程过程调用或RPC。
在本教程中,我们将使用RabbitMQ构建一个RPC系统:一个客户端和一个RPC服务器。我们将创建一个返回斐波那契数字的模拟RPC服务。
整个过程示意图如下:
客户端将请求发送至rpc_queue(我们定义的消息队列),然后等待响应;服务端获取请求,并处理请求,然后将请求结果返回给队列,客户端得知请求被响应后获取结果。
在结果被响应之前,客户端是被阻塞的,主线程会等待RPC响应
如果每个RPC请求都创建一个回调队列。这是非常低效,我们创建一个单一的客户端回调队列。
这引发了一个新的问题,在该队列中收到回复时,不清楚回复属于哪个请求。这就需要用到 correlationId属性。我们为没有请求设置唯一的correlationId值。然后,当我们在回调队列中收到一条消息时,我们将获取这个值,将响应与请求的进行correlationId匹配。如果我们一致就是我们需要的结果,否则就不是。
客户端代RPCClient 码如下:
package com.adtec.rabbitmq;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Envelope;
import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeoutException;
public class RPCClient {
private Connection connection;
private Channel channel;
private String requestQueueName = "rpc_queue";
private String replyQueueName;
public RPCClient() throws IOException, TimeoutException {
//建立一个连接和一个通道,并为回调声明一个唯一的'回调'队列
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
connection = factory.newConnection();
channel = connection.createChannel();
//定义一个临时变量的接受队列名
replyQueueName = channel.queueDeclare().getQueue();
}
//发送RPC请求
public String call