当前位置: 首页 > news >正文

8.RabbitMQ系列之RPC

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. 总结

1

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();
    }

2

相关文章:

  • 2022-10-15 Docker Harbor安装
  • 安装ROS-Academy-for-Beginners教学包时安装依赖的时候老是失败
  • OpenCV实战案例——车道线识别
  • 【Linux】进程控制 创建/终止/等待/替换
  • 【Linux】远程登陆、远程开发以及Vim的使用
  • Java项目本地部署宝塔搭建实战校园二手市场系统源码
  • EMC诊断技术及电磁兼容理论设计
  • 洛谷——【入门1】顺序结构题解
  • 计算机视觉 立体视觉极简一览
  • envoy开发调试环境搭建
  • 多线程轮流打印 ABC
  • SpringCloud整合spring security+ oauth2+Redis实现认证授权
  • 轻量级开源ROS 的机器人设备(一)
  • java基于微信小程序的校园报修系统 uniapp小程序
  • IDEA详细配置『JDK | Maven | Tomcat』
  • Apache Spark Streaming 使用实例
  • bearychat的java client
  • Gradle 5.0 正式版发布
  • HashMap ConcurrentHashMap
  • Java 最常见的 200+ 面试题:面试必备
  • js继承的实现方法
  • leetcode-27. Remove Element
  • Less 日常用法
  • nginx 负载服务器优化
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • PhantomJS 安装
  • Python语法速览与机器学习开发环境搭建
  • scala基础语法(二)
  • Service Worker
  • Spring Cloud Feign的两种使用姿势
  • Vue2 SSR 的优化之旅
  • 阿里云前端周刊 - 第 26 期
  • 从 Android Sample ApiDemos 中学习 android.animation API 的用法
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 分布式事物理论与实践
  • 前端面试之闭包
  • 如何学习JavaEE,项目又该如何做?
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 为物联网而生:高性能时间序列数据库HiTSDB商业化首发!
  • 做一名精致的JavaScripter 01:JavaScript简介
  • 2017年360最后一道编程题
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 阿里云服务器购买完整流程
  • 仓管云——企业云erp功能有哪些?
  • 东超科技获得千万级Pre-A轮融资,投资方为中科创星 ...
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • #{} 和 ${}区别
  • $var=htmlencode(“‘);alert(‘2“); 的个人理解
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C语言)二分查找 超详细
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • *setTimeout实现text输入在用户停顿时才调用事件!*
  • *上位机的定义
  • .net framework4与其client profile版本的区别