1. RPC

Remote Procedure Call:远程过程调用,一次远程过程调用的流程即客户端发送一个请求到服务端,服务端根据请求信息进行处理后返回响应信息,客户端收到响应信息后结束

2. Client interface客户端接口

为了说明如何使用RPC服务,我们将把“发送方”和“接收方”更改为“客户端”和“服务器”。当我们调用服务时,我们将得到我们对应的斐波那契值

Integer response = (Integer) template.convertSendAndReceive
(exchange.getName(), "rpc", 5);
System.out.println(" [.] Got '" + response + "'");
3. Callback queue回调队列

一般来说,通过RabbitMQ执行RPC很容易。客户端发送请求消息,服务器进行回复。为了接收响应,我们需要随请求一起发送“回调”队列地址。当我们使用上述convertSendAndReceive()方法时,Spring AMQP的RabbitTemplate为我们处理回调队列。使用RabbitTemplate时,无需执行任何其他设置

Message properties消息属性

  • deliveryMode:将消息标记为持久(值为2)或瞬态(任何其他值)
  • contentType: 用于描述编码的mime-type。例如,对于经常使用的JSON编码,将此属性设置为:application/JSON是一种很好的做法
  • replyTo:常用于命名回调队列
  • correlationId: 用于将RPC响应与请求关联
4. Correlation Id关联ID

Spring AMQP允许您关注正在使用的消息方式,并隐藏支持此方式所需的消息管道的详细信息。例如,本机客户端通常会为每个RPC请求创建一个回调队列。这效率很低,所以另一种方法是为每个客户端创建一个回调队列

这引发了一个新问题,在该队列中收到响应后,不清楚响应属于哪个请求。此时将使用correlationId属性。Spring AMQP自动为每个请求设置唯一值。此外,它还处理拥有正确correlationID的响应

Spring AMQP使RPC样式更容易的一个原因是,有时您可能希望忽略回调队列中的未知消息,而不是由于错误而失败。这是由于服务器端可能存在竞争条件。虽然不太可能,但RPC服务器可能会在向我们发送应答之后,但在发送请求的确认消息之前死亡。如果发生这种情况,重新启动的RPC服务器将再次处理该请求。Spring AMQP客户端优雅地处理重复的响应,理想情况下RPC应该是幂等的

4. 总结

RPC工作流程如下:

  1. RpcConfig新建一个直连交换器rpc并绑定队列
  2. 客户端调用convertSendAndReceive方法,设置exchange、routing key、message
  3. 请求并发送至队列rpc.requests
  4. 服务端监听队列中的客户端请求,请求一旦进入队列,服务端开始工作并使用队列的replyTo字段进行响应,
  5. 客户端等待回调队列中消息,当消息到达,其核查correlationId字段,如果匹配,则返回响应消息给应用。这在RabbitTemplate自动实现
5. 完整代码
@Configuration
public class RpcConfig { @Bean
public DirectExchange rpc() {
return new DirectExchange("rpc");
} private static class ServerConfig { @Bean
public Queue rpcQueue() {
return new Queue("rpc.requests");
} @Bean
public Binding binding(DirectExchange rpc,
Queue rpcQueue) {
return BindingBuilder.bind(rpcQueue)
.to(rpc)
.with("rpc");
}
}
}
@Component
public class RpcClient { private RabbitTemplate rabbitTemplate; public RpcClient(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
} public void send() {
System.out.println(" [客户端] 发送请求10");
Integer response = (Integer) rabbitTemplate.convertSendAndReceive("rpc", "rpc", 10);
System.out.println(" [客户端] 收到响应 " + response + "");
}
}
@Component
public class RpcServer { @RabbitListener(queues = "rpc.requests")
public int fibonacci(int n) {
System.out.println(" [服务端] 收到请求" + n);
int result = fib(n);
System.out.println(" [服务端] 响应请求 " + result);
return result;
} public int fib(int n) {
return n == 0 ? 0 : n == 1 ? 1 : (fib(n - 1) + fib(n - 2));
} }
@SpringBootTest
public class RabbitTest {
@Autowired
private RpcClient rpcClient; @Test
public void testRpc() {
rpcClient.send();
}

欢迎关注公众号算法小生沈健的技术博客

8.RabbitMQ系列之RPC的更多相关文章

  1. RabbitMQ系列教程之六:远程过程调用(RPC)

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

  2. RabbitMQ系列教程之六:远程过程调用(RPC)(转载)

    RabbitMQ系列教程之六:远程过程调用(RPC) 远程过程调用(Remote Proceddure call[RPC]) (本实例都是使用的Net的客户端,使用C#编写) 在第二个教程中,我们学习 ...

  3. Python操作rabbitmq系列(六):进行RPC调用

    此刻,我们已经进入第6章,是官方的最后一个环节,但是,并非本系列的最后一个环节.因为在实战中还有一些经验教训,并没体现出来.由于马上要给同事没培训celery了.我也来不及写太多.等后面,我们再慢慢补 ...

  4. rabbitmq系列五 之远程过程调用(RPC)

    1.远程过程调用(RPC) 在第二篇教程中我们介绍了如何使用工作队列(work queue)在多个工作者(woker)中间分发耗时的任务. 可是如果我们需要将一个函数运行在远程计算机上并且等待从那儿获 ...

  5. 在Node.js中使用RabbitMQ系列二 任务队列

    在上一篇文章在Node.js中使用RabbitMQ系列一 Hello world我有使用一个任务队列,不过当时的场景是将消息发送给一个消费者,本篇文章我将讨论有多个消费者的场景. 其实,任务队列最核心 ...

  6. RabbitMQ中的RPC实现

    1.RPC简述 RPC,Remote Procedure Call 远程过程调用.通俗讲,两段程序不在同一个内存空间,无法直接通过方法名调用,就需要通过网络通信方式调用.对于RabbitMQ,本身就是 ...

  7. RabbitMQ系列(四)RabbitMQ事务和Confirm发送方消息确认——深入解读

    RabbitMQ事务和Confirm发送方消息确认--深入解读 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器 ...

  8. RabbitMQ系列(三)RabbitMQ交换器Exchange介绍与实践

    RabbitMQ交换器Exchange介绍与实践 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchang ...

  9. RabbitMQ系列(二)深入了解RabbitMQ工作原理及简单使用

    深入了解RabbitMQ工作原理及简单使用 RabbitMQ系列文章 RabbitMQ在Ubuntu上的环境搭建 深入了解RabbitMQ工作原理及简单使用 RabbitMQ交换器Exchange介绍 ...

随机推荐

  1. 技术分享 | MySQL Group Replication集群对IP地址的限制导致的一些问题与解决办法

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1. 遇到问题 测试人员小玲准备在docker环境中部署MGR集群进行一些测试,她有三个容器,容器IP分别是: 172.3 ...

  2. 大数据管理系统架构Hadoop

    Hadoop 起源于Google Lab开发的Google File System (GFS)存储系统和MapReduce数据处理框架.2008年,Hadoop成了Apache上的顶级项目,发展到今天 ...

  3. 【沥血整理】灰度(二值)图像重构算法及其应用(morphological reconstruction)。

    不记得是怎么接触并最终研究这个课题的了,认识我的人都知道我是没有固定的研究对象的,一切看运气和当时的兴趣.本来研究完了就放在那里了,一直比较懒的去做总结,但是想一想似乎在网络上就没有看到关于这个方面的 ...

  4. Git 08 IDEA撤销添加

    参考源 https://www.bilibili.com/video/BV1FE411P7B3?spm_id_from=333.999.0.0 版本 本文章基于 Git 2.35.1.2 如果将不想添 ...

  5. [游记]CSP 2021 J/S

    这一次,也许是我的OI生涯的转折点了--能过,学习OI的时间就不会减少:但不能过,就会减少学习OI的时间-- 上午(S组) 6:00起床.去吃早餐,结果因为边喝粥边喝牛奶导致肚子疼.(我在这里劝大家, ...

  6. SpringBoot整合Redis实现常用功能

    SpringBoot整合Redis实现常用功能 建议大小伙们,在写业务的时候,提前画好流程图,思路会清晰很多. 文末有解决缓存穿透和击穿的通用工具类. 1 登陆功能 我想,登陆功能是每个项目必备的功能 ...

  7. Excelize 2.3.1 发布,Go 语言 Excel 文档基础库,支持加密表格文档

    Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Exc ...

  8. github action 实现CI/CD

    两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库 1.GitHub Actions 是什么? 大家知道,持续集成由很多操作组成,比如抓取代码.运行测试. ...

  9. [HNOI2011]卡农 (数论计数,DP)

    题面 原题面 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则. 他将声音分成 n n n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 1 1 ...

  10. 第六十篇:Vue的基本使用

    好家伙,要来了,经典"hello world" 试用一下vue ① 导入 vue.js的 script 脚本文件 ② 在页面中声明一个将要被vue所控制的DOM区域 ③ 创建vm实 ...