rabbitmq学习(四):利用rabbitmq实现远程rpc调用
一、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调用的更多相关文章
- 【c#】RabbitMQ学习文档(六)RPC(远程调用)
远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习了如何使用工作队列在多个工作实例之间分配耗时的任务. ...
- 【RabbitMQ学习之一】RabbitMQ入门
环境 win7 rabbitmq-server-3.7.17 Erlang 22.1 RabbitMQ使用Erlang语言开发消息中间件.RabbitMQ基于AMQP(高级消息队列协议)协议,更适合业 ...
- rabbitMQ学习2-Python与rabbitmq
python客户端 # rabbitmq官方推荐的python客户端pika模块 pip3 install pika 应用场景1:单发送单接收 1.生产-消费者模型 P 是生产者 C 是消费者 中间h ...
- rabbitmq学习-如何安装rabbitmq
学习当然还是需要看官网地址的哈 官网地址 你可能会说老铁,看不懂英文咋办?我只能说各大翻译软件以及广大网友总有一款是你喜欢的 广大网友翻译的 中文文档 什么是rabbitmq? rabbitmq (R ...
- [RabbitMQ学习笔记] - 初识RabbitMQ
RabbitMQ是一个由erlang开发的AMQP的开源实现. 核心概念 Message 消息,消息是不具名的,它由消息头和消息体组成,消息体是不透明的,而消息头则由 一系列的可选属性组成,这些属性包 ...
- rabbitmq学习(二):rabbitmq(消息队列)的作用以及rabbitmq之直连交换机
前言 上篇介绍了AMQP的基本概念,组成及其与rabbitmq的关系.了解了这些东西后,下面我们开始学习rabbitmq(消息队列)的作用以及用java代码和rabbitmq通讯进行消息发布和接收.因 ...
- RabbitMQ学习之旅(一)
RabbitMQ学习总结(一) RabbitMQ简介 RabbitMQ是一个消息代理,其接收并转发消息.类似于现实生活中的邮局:你把信件投入邮箱的过程,相当于往队列中添加信息,因为所有邮箱中的信件最终 ...
- 自研发RPC调用框架
自主研发设计RPC远程调用框架,实现服务自动注册,服务发现,远程RPC调用,后续实现服务负载均衡 主要包括:客户端服务,服务端,服务发现,服务注册 github地址:https://github.co ...
- RabbitMQ学习之基于spring-rabbitmq的RPC远程调用
http://blog.csdn.net/zhu_tianwei/article/details/40920985 spring-rabbitmq中实现远程接口调用,主要在com.rabbitmq.s ...
随机推荐
- array2xml xml2array
array2xml/** * * 将简单数组转化为简单的xml * @param string $data 要进行转化的数组 * @param string $tag ...
- char *strstr(const char *str1, const char *str2);
[FROM MSDN && 百科] 原型:char *strstr(const char *str1, const char *str2); #include<string.h& ...
- CCPC2018-湖南全国邀请赛 Solution
A - Easy $h$-index 后缀扫一下 #include <bits/stdc++.h> using namespace std; #define ll long long #d ...
- [转]Birdfont 2.10 发布,字体编辑器
最近在忙大数据.黑天鹅算法实盘测试 许久没有更新字库方面的资料,汗一个... 今天转一个 :Birdfont 2.10 发布,字体编辑器 字体编辑器,向来很少,除了fontlab的几个昂贵的商业版,就 ...
- python: 随机选择
想从一个序列中随机抽取若干元素,或者想生成几个随机数. random 模块有大量的函数用来产生随机数和随机选择元素.比如,要想从一个序列中随机的抽取一个元素,可以使用random.choice() : ...
- 20145221 《Java程序设计》实验报告三:敏捷开发与XP实践
20145221 <Java程序设计>实验报告三:敏捷开发与XP实践 实验要求 以结对编程的方式编写一个软件,Blog中要给出结对同学的Blog网址 记录TDD和重构的过程,测试代码不要少 ...
- 从0开始学习 GITHUB 系列之「GIT 进阶」【转】
本文转载自:http://stormzhang.com/github/2016/06/16/learn-github-from-zero5/ 版权声明:本文为 stormzhang 原创文章,可以随意 ...
- git如何自动打补丁
答:git am --reject jello.patch (如果打补丁失败,会自动生成rej文件)
- 【图片下载-代码】java下载网络图片资源例子
/** * @Description 下载网络图片资源 * @param imageUrl 图片地址 * @return String 下载后的地址 * @author SUNBIN * @date ...
- 【软件是否安装】linux下如何查看某软件是否已安装
因为Linux安装软件的方式比较多,所以没有一个通用的办法能查到某些软件是否安装了.总结起来就是这样几类: 1.rpm包安装的,可以用rpm -qa看到,如果要查找某软件包是否安装,用 rpm -qa ...