RabbitMQ之RPC
来源:互联网 发布:淘宝鹊桥活动怎样 编辑:程序博客网 时间:2024/05/17 02:13
首先要弄明白,RPC是个什么东西。(RPC) Remote Procedure Call Protocol 远程过程调用协议
在一个大型的公司,系统由大大小小的服务构成,不同的团队维护不同的代码,部署在不同的机器。但是在做开发时候往往要用到其它团队的方法,因为已经有了实现。但是这些服务部署不同的机器上,想要调用就需要网络通信,这些代码繁琐且复杂,一不小心就会写的很低效。RPC协议定义了规划,其它的公司都给出了不同的实现。比如微软的wcf,以及现在火热的WebApi。
RPC工作流程:
1)、客户端启动时,创建了一个匿名的回调队列。
2)、在一个RPC请求中,客户端发送一个消息,它有两个属性:1.REPLYTO,用来设置回调队列名;2.correlationId,对于每个请求都被设置成唯一的值。
3)、请求被发送到rpc_queue队列.
4)、RPC工作者(又名:服务器)等待接收该队列的请求。当收到一个请求,它就会处理并把结果发送给客户端,使用的队列是replyTo字段指定的。
5)、客户端等待接收回调队列中的数据。当接到一个消息,它会检查它的correlationId属性。如果它和设置的相匹配,就会把响应返回给应用程序。
服务端
import com.rabbitmq.client.*;import com.ydh.util.ConnectionFactoryUtil;import java.io.IOException;//RPC调用服务端 public class RPCService { private static final String RPC_QUEUE_NAME = "rpc_queue"; public static void main(String[] argv) { Connection connection; try { connection = ConnectionFactoryUtil.getInstance(); Channel channel = connection.createChannel(); channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null); channel.basicQos(1); System.out.println(" [x] Awaiting RPC requests"); Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { AMQP.BasicProperties replyProps = new AMQP.BasicProperties .Builder() .correlationId(properties.getCorrelationId()) .build(); String response = ""; try { String message = new String(body, "UTF-8"); int n = Integer.parseInt(message); System.out.println(" [.] fib(" + message + ")"); response += fib(n); } catch (RuntimeException e) { System.out.println(" [.] " + e.toString()); } finally { channel.basicPublish("", properties.getReplyTo(), replyProps, response.getBytes("UTF-8")); channel.basicAck(envelope.getDeliveryTag(), false); } } }; channel.basicConsume(RPC_QUEUE_NAME, false, consumer); } catch (Exception e) { e.printStackTrace(); } } private static int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; return fib(n-1) + fib(n-2); }}
客户端
import com.rabbitmq.client.*;import com.ydh.util.ConnectionFactoryUtil;import java.io.IOException;import java.util.UUID;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;//RPC调用客户端 public class RPCClient { private Connection connection; private Channel channel; private String requestQueueName = "rpc_queue"; private String replyQueueName; public RPCClient() throws Exception { // • 先建立一个连接和一个通道,并为回调声明一个唯一的'回调'队列 connection = ConnectionFactoryUtil.getInstance(); channel = connection.createChannel(); // • 注册'回调'队列,这样就可以收到RPC响应 replyQueueName = channel.queueDeclare().getQueue(); } // 发送RPC请求 public String call(String message) throws IOException, InterruptedException { String corrId = UUID.randomUUID().toString(); AMQP.BasicProperties props = new AMQP.BasicProperties .Builder() .correlationId(corrId) .replyTo(replyQueueName) .build(); channel.basicPublish("", requestQueueName, props, message.getBytes("UTF-8")); final BlockingQueue<String> response = new ArrayBlockingQueue<>(1); channel.basicConsume(replyQueueName, true, new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { if (properties.getCorrelationId().equals(corrId)) { response.offer(new String(body, "UTF-8")); } } }); return response.take(); } public void close() throws IOException { connection.close(); }}
客户端main主函数
public class RPCMain { public static void main(String[] args) throws Exception { RPCClient rpcClient = new RPCClient(); System.out.println(" [x] Requesting getMd5String(abc)"); String response = rpcClient.call("abc"); System.out.println(" [.] Got '" + response + "'"); rpcClient.close(); }}
先运行服务端,再运行RPCMain,发送消息调用RPC。
这里介绍的是该设计不是实现RPC服务的唯一可能,但它有一些重要的优点:
1)如果RPC服务器速度太慢,你可以通过运行多个RPC服务器。尝试在一个新的控制台上运行第二RPCServer。
2)RPC客户端只发送和接收一个消息。不需要queueDeclare那样要求同步调用。因此,RPC客户端只需要在一个网络上发送和接收为一个单一的RPC请求。
- RabbitMQ之RPC实现
- RabbitMq之RPC
- RabbitMQ之RPC
- RabbitMQ 之六 RPC
- python系列之 RabbitMQ - RPC
- RabbitMQ 之 RPC 初探(Java)
- rabbitmq rpc
- RabbitMQ RPC
- RabbitMQ RPC
- RabbitMQ学习 .NET Client之RPC
- RabbitMQ学习之基于spring-rabbitmq的RPC远程调用
- RabbitMQ学习之基于spring-rabbitmq的RPC远程调用
- RabbitMQ学习之基于spring-rabbitmq的RPC远程调用
- RabbitMQ学习(六).NET Client之RPC
- RabbitMQ学习之远程过程调用(RPC)(java)
- RabbitMQ学习(六)之远程过程调用(RPC)(java)
- RabbitMQ案例七之RPC远程过程调用
- Nova-RPC rabbitmq
- 读者写者模型(概念&与生产消费者的区别¥读写优先级问题)
- Android Studio 2.3 版本配置Genymotion
- 如何将 TCP/IP 端口映射到 NUMA 节点
- JDK5线程池与用线程池启动定时器
- TWAIN扫描组件Dynamic .NET TWAIN v7.1发布,将图像保存为多页TIFF
- RabbitMQ之RPC
- 数据传输中CRC校验码的实现
- MVC、MVP、MVVM使用关系总结
- 解决String类型存入Oracle数据库中对应的TIMESTAMP类型
- 同一服务器下配置多域名,去掉Tomcat端口号,Nginx反向代理做转发
- Android中如何隐藏掉顶部通知栏
- list和set集合的几种遍历方式
- 二、JSX的介绍
- Objective-c新特性