RPC功能的实现
来源:互联网 发布:变态的皇帝知乎 编辑:程序博客网 时间:2024/06/03 13:34
看了一下网络上关于rabbitMq实现RPC都是在服务端实现一个产生斐波那契数列的函数,然后将结果返回给客户端打印,所以索性去官网看了一下这一块的相关内容,但是官网上给的例子好像也是这个(晕...),既然那个例子这么经典,那么必然值得研究一下~
首先需要明确几个概念:
1.Callback queue 回调队列
一个客户端向服务器发送请求,服务器端处理请求后,将其处理结果保存在一个存储体中。而客户端为了获得处理结果,那么客户在向服务器发送请求时,同时发送一个回调队列地址。
2.Correlation id 关联标识
一个客户端可能会发送多个请求给服务器,当服务器处理完后,客户端无法辨别在回调队列中的响应具体和那个请求时对应的。为了处理这种情况,客户端在发送每个请求时,同时会附带一个独有correlation_id属性,这样客户端在回调队列中根据correlation_id字段的值就可以分辨此响应属于哪个请求。
同时RPC又分为异步和同步,这里采用异步队列的方式实现RPC功能。
流程:
1.客户端初始化
启动后,创建一个独有的回调队列
2.客户端发送请求
某个应用将请求信息交给客户端,然后客户端发送RPC请求,在发送RPC请求到RPC请求队列时,客户端至少发送带有reply_to以及correlation_id两个属性的信息
3.服务端接收请求
等待接受客户端发来RPC请求,当请求出现的时候,服务器从RPC请求队列中取出请求,然后处理后,将响应发送到reply_to指定的回调队列中
4.客户端接收请求
客户端等待回调队列中出现响应,当响应出现时,它会根据响应中correlation_id字段的值,将其返回给对应的应用
相关代码:
客户端:
public class Client { private Connection connection; private Channel channel; private String requestQueueName = "rpc_queue"; private String replyQueueName; private QueueingConsumer consumer; public Client() throws Exception { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); connection = factory.newConnection(); channel = connection.createChannel(); replyQueueName = channel.queueDeclare().getQueue(); consumer = new QueueingConsumer(channel); channel.basicConsume(replyQueueName, true, consumer); } public String call(String message) throws Exception { String response = null; String corrId = UUID.randomUUID().toString(); BasicProperties props = new BasicProperties.Builder().correlationId(corrId).replyTo(replyQueueName).build(); channel.basicPublish("", requestQueueName, props, message.getBytes("UTF-8")); while (true) { QueueingConsumer.Delivery delivery = consumer.nextDelivery(); if (delivery.getProperties().getCorrelationId().equals(corrId)) { response = new String(delivery.getBody(), "UTF-8"); break; } } return response; } public void close() throws Exception { connection.close(); } public static void main(String[] argv) { Client fibonacciRpc = null; String response = null; try { fibonacciRpc = new Client(); System.out.println("RPCClient [x] Requesting fib(30)"); response = fibonacciRpc.call("30"); System.out.println("RPCClient [.] Got '" + response + "'"); } catch (Exception e) { e.printStackTrace(); } finally { if (fibonacciRpc != null) { try { fibonacciRpc.close(); } catch (Exception ignore) { } } } }}
服务端
public class Server { private static final String RPC_QUEUE_NAME = "rpc_queue"; private static int fib(int n) { if (n == 0) return 0; if (n == 1) return 1; return fib(n - 1) + fib(n - 2); } public static void main(String[] argv) { Connection connection = null; Channel channel = null; try { ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); connection = factory.newConnection(); channel = connection.createChannel(); channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null); channel.basicQos(1); QueueingConsumer consumer = new QueueingConsumer(channel); channel.basicConsume(RPC_QUEUE_NAME, false, consumer); System.out.println("RPCServer [x] Awaiting RPC requests"); while (true) { String response = null; QueueingConsumer.Delivery delivery = consumer.nextDelivery(); BasicProperties props = delivery.getProperties(); BasicProperties replyProps = new BasicProperties.Builder().correlationId(props.getCorrelationId()).build(); try { String message = new String(delivery.getBody(), "UTF-8"); int n = Integer.parseInt(message); System.out.println("RPCServer [.] fib(" + message + ")"); response = "" + fib(n); } catch (Exception e) { System.out.println(" [.] " + e.toString()); response = ""; } finally { channel.basicPublish("", props.getReplyTo(), replyProps, response.getBytes("UTF-8")); channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); } } } catch (Exception e) { e.printStackTrace(); } finally { if (connection != null) { try { connection.close(); } catch (Exception ignore) { } } } }}
参考文章:
https://www.rabbitmq.com/tutorials/tutorial-six-java.html
http://www.jianshu.com/p/13055d276f96
- RPC功能的实现
- RPC通信功能实现
- 自己实现简单RPC功能
- 自己实现简单RPC功能
- RPC功能目标及实现
- 自己实现简单RPC功能
- RPC的实现
- Hadoop的RPC实现
- 简单的RPC实现
- RPC框架的实现
- 简单实现的RPC
- Hadoop的RPC实现
- 【跟我看看GXT】基于GXT的RPC和MVC实现登录功能
- 【跟我看看GXT】基于GXT的RPC和MVC实现登录功能
- 基于Netty的RPC简单框架实现(五):功能测试与性能测试
- 带有HA功能的Hadoop Client端RPC实现原理与代码分析
- RakNet的远程功能调用(RPC)服务端
- RakNet的远程功能调用(RPC)客户端
- 【POJ 2236】Wireless NetWork(并查集应用)
- Linux中查找指定大小或者指定内容的文件
- Java线程 ,线程同步详解,单例
- CF771C:Bear and Tree Jumps(树形dp & 树上距离和)
- Hibernate
- RPC功能的实现
- java杨辉三角代码编写
- N皇后问题
- plsql develop 连接远程数据库
- Hive分区表操作
- 谈谈RunLoop
- Codeforces Round #426 (Div. 2)The Meaningless Game【数学题】【水题】
- 信息标记与信息提取
- P3776工资管理