一、rabbitmq实现rpc调用的原理

·rabbitmq实现rpc的原理是:客户端向一个队列中发送消息,并注册一个回调的队列用于接收服务端返回的消息,该消息需要声明一个叫做correaltionId的属性,该属性将是该次请求的唯一标识。服务端在接受到消息(在需要时可以验证correaltionId)后,处理消息,并将消息发送到客户端注册的回调队列中。原理图如下:  

  

二、代码实现

  下面我们将模拟实现一个rpc客户端和rpc服务端。客户端给服务端发送message,服务端收到后处理message,再将处理后的消息返给客户端

  rpc客户端

  

/**
* rpc客户端
*/
public class RpcClient {
//发送消息的队列名称
private static final String RPC_QUEUE_NAME = "rpc_queue"; public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
Channel channel = null;
try {
connection = connectionFactory.newConnection();
channel = connection.createChannel();
//创建回调队列
String callbackQueue = channel.queueDeclare().getQueue();
//创建回调队列,消费者从回调队列中接收服务端传送的消息
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(callbackQueue,true,consumer); //创建消息带有correlationId的消息属性
String correlationId = UUID.randomUUID().toString();
AMQP.BasicProperties basicProperties = new AMQP.BasicProperties().builder().correlationId(correlationId).replyTo(callbackQueue).build();
String message = "hello rabbitmq";
channel.basicPublish("",RPC_QUEUE_NAME,basicProperties,message.getBytes());
System.out.println("RpcClient send message " + message + ", correaltionId = " + correlationId); //接收回调消息
while (true){
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String receivedCorrelationId = delivery.getProperties().getCorrelationId();
if(correlationId.equals(receivedCorrelationId)){
System.out.println("RpcClient receive format message " + new String(delivery.getBody(), "UTF-8") + ", correaltionId = " + correlationId);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
}

  rpc服务端

  

/**
* rpc服务器
*/
public class RpcServer {
private static final String RPC_QUEUE_NAME = "rpc_queue"; private static String format(String message){
return "......" + message + "......";
} public static void main(String[] args) {
ConnectionFactory connectionFactory = new ConnectionFactory();
Connection connection = null;
try {
connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(RPC_QUEUE_NAME,false,false,false,null);
QueueingConsumer consumer = new QueueingConsumer(channel);
//声明消费者预取的消息数量
channel.basicQos(1);
channel.basicConsume(RPC_QUEUE_NAME,false,consumer);//采用手动回复消息
System.out.println("RpcServer waitting for receive message"); while (true){
//接收并处理消息
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody(), "UTF-8");
System.out.println("RpcServer receive message " + message);
String response = format(message);
//确认收到消息
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false); //取出消息的correlationId
AMQP.BasicProperties properties = delivery.getProperties();
String correlationId = properties.getCorrelationId(); //创建具有与接收消息相同的correlationId的消息属性
AMQP.BasicProperties replyProperties = new AMQP.BasicProperties().builder().correlationId(correlationId).build();
channel.basicPublish("",properties.getReplyTo(),replyProperties,response.getBytes());
} } catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

  先运行服务端,再运行客户端,结果如下:

  RpcClient

  

  RpcServer

  

 

代码gitbu地址:https://github.com/wutianqi/rabbitmq-learn.git

参考资料:https://www.cnblogs.com/LipeiNet/p/5980802.html

rabbitmq学习(四):利用rabbitmq实现远程rpc调用的更多相关文章

  1. 【c#】RabbitMQ学习文档(六)RPC(远程调用)

    远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...

  2. 【RabbitMQ学习之一】RabbitMQ入门

    环境 win7 rabbitmq-server-3.7.17 Erlang 22.1 RabbitMQ使用Erlang语言开发消息中间件.RabbitMQ基于AMQP(高级消息队列协议)协议,更适合业 ...

  3. rabbitMQ学习2-Python与rabbitmq

    python客户端 # rabbitmq官方推荐的python客户端pika模块 pip3 install pika 应用场景1:单发送单接收 1.生产-消费者模型 P 是生产者 C 是消费者 中间h ...

  4. rabbitmq学习-如何安装rabbitmq

    学习当然还是需要看官网地址的哈 官网地址 你可能会说老铁,看不懂英文咋办?我只能说各大翻译软件以及广大网友总有一款是你喜欢的 广大网友翻译的 中文文档 什么是rabbitmq? rabbitmq (R ...

  5. [RabbitMQ学习笔记] - 初识RabbitMQ

    RabbitMQ是一个由erlang开发的AMQP的开源实现. 核心概念 Message 消息,消息是不具名的,它由消息头和消息体组成,消息体是不透明的,而消息头则由 一系列的可选属性组成,这些属性包 ...

  6. rabbitmq学习(二):rabbitmq(消息队列)的作用以及rabbitmq之直连交换机

    前言 上篇介绍了AMQP的基本概念,组成及其与rabbitmq的关系.了解了这些东西后,下面我们开始学习rabbitmq(消息队列)的作用以及用java代码和rabbitmq通讯进行消息发布和接收.因 ...

  7. RabbitMQ学习之旅(一)

    RabbitMQ学习总结(一) RabbitMQ简介 RabbitMQ是一个消息代理,其接收并转发消息.类似于现实生活中的邮局:你把信件投入邮箱的过程,相当于往队列中添加信息,因为所有邮箱中的信件最终 ...

  8. 自研发RPC调用框架

    自主研发设计RPC远程调用框架,实现服务自动注册,服务发现,远程RPC调用,后续实现服务负载均衡 主要包括:客户端服务,服务端,服务发现,服务注册 github地址:https://github.co ...

  9. RabbitMQ学习之基于spring-rabbitmq的RPC远程调用

    http://blog.csdn.net/zhu_tianwei/article/details/40920985 spring-rabbitmq中实现远程接口调用,主要在com.rabbitmq.s ...

随机推荐

  1. Linux系统——FTP

    FTP连接及传输模式1. 控制连接:TCP21,用于发送FTP命令信息2. 数据连接:TCP20,用于上传.下载数据3. 数据连接的建立类型:(1)主动模式:服务器制动发起数据连接首先由客户端向服务端 ...

  2. ZOJ Monthly, January 2018 Solution

    A - Candy Game 水. #include <bits/stdc++.h> using namespace std; #define N 1010 int t, n; int a ...

  3. 字王4K云字库入驻github

    字王4K云字库入驻github 网址:https://github.com/ziwang-com/zw4kFont   2015.3.28,字王4K云字库入驻github,原本或早或晚,不过这几天在g ...

  4. python 字节字符串上的字符串操作

    问题:想在字节字符串上执行普通的文本操作(比如移除,搜索和替换). 解决方案 1)字节字符串同样也支持大部分和文本字符串一样的内置操作.比如: >>> data = b'Hello ...

  5. Django学习笔记之Ajax与文件上传

      Ajax简介 AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”.即使用Javascript语言与服务器进行异步交互,传输 ...

  6. MAC nginx代理设置

    问题: 10.154.156.83:10081私服不存在了.但是不能改.用nginx代理至maven.xx.cn 增加换回地址: sudo ifconfig lo0 add 10.154.156.83 ...

  7. 如何为openwrt生成补丁

    答:使用quilt工具 步骤如下: 1. 配置quilt $cat> ~/.quiltrc <<EOF QUILT_DIFF_ARGS="--no-timestamps - ...

  8. Thinking in java note1

    Part information collecting from http://blog.csdn.net/leonliu06/article/details/78638841 1. 如果已经定义了一 ...

  9. Android 旋转、平移、缩放和透明度渐变的补间动画

    补间动画就是通过对场景里的对象不断进行图像变化来产生动画效果.在实现补间动画时,只需要定义开始和结束的“关键帧”,其他过渡帧由系统自动计算并补齐.在Android中,提供了以下4种补间动画. **1. ...

  10. BZOJ 3064 CPU监控

    题目链接:CPU监控 学习一番线段树的历史标记- 这道题就是区间加法,区间赋值,要询问区间最大值 和 区间历史最大值的最大值. 然后这种题就是在现有标记的基础上多弄一套标记,维护这个点出现过的最大的标 ...