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 ...
随机推荐
- MySQL从删库到跑路(三)——SQL语言
作者:天山老妖S 链接:http://blog.51cto.com/9291927 一.SQL语言简介 1.SQL语言简介 SQL是结构化查询语言(Structured Query Language) ...
- Python 在字符串中处理html 和xml
问题: 想将HTML 或者XML 实体如&entity; 或&#code; 替换为对应的文本.再者,你需要转换文本中特定的字符(比如<, >, 或&). 解决方案: ...
- 【转载】JS Number类型数字位数及IEEE754标准
JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...
- JSDoc 注释规范
命令名描述 @param @argument 指定参数名和说明来描述一个函数参数@returns 描述函数的返回值@author 指示代码的作者@deprecated 指示一个函数已经废弃,而且在将来 ...
- 微信小程序:WXSS 样式
微信小程序:WXSS 样式 一.WXSS 样式 XSS 具有 CSS 大部分的特性,小程序在 WXSS 也做了一些扩充和修改. 1,新增了尺寸单位: 在写 CSS 样式时,开发者需要考虑到手机设备的屏 ...
- 20145105 《Java程序设计》第5周学习总结
20145105 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 异常处理 一.语法与继承架构 (一)使用try.catch 执行流程 尝试执行try区块中程序代码 如果出现 ...
- SSH防止暴力破解--fail2ban
一.ssh密钥对无交互登录 实战1:通过密钥进行sshd服务认证 服务端:linl_S IP:10.0.0.15 客户端:lin_C IP:10.0.0.16 1)在客户端生成密钥对 ...
- 《F4+2 团队项目需求分析改进》
a.分析<动态的太阳系模型项目需求规格说明书>初稿的不足. 任务概述描述的有些不具体,功能的规定不详细,在此次作业进行了修改. b.参考<构建之法>8.5节功能的定位和优先级, ...
- Cloud Native 环境
当今软件行业正发生着巨变.自上世纪50年代计算机诞生以来,软件从最初的手工作坊式的交付方式,逐渐演变成为了职业化开发.团队化开发,进而定制了软件件行业的相关规范,形成了软件产业. 今天,无论是大型企业 ...
- 这是一份很详细的 Retrofit 2.0 使用教程(含实例讲解)
前言 在Andrroid开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库 今天,我将献上一份非常详细Retrofit v2.0的使用教程,希望你们会 ...