关于RPC的介绍请参考百度百科里的关于RPC的介绍:http://baike.baidu.com/view/32726.htm#sub32726

现在来看看Rabbitmq中RPC吧!RPC的工作示意图如下:

上图中的C代表客户端,S表示服务器端;Rabbitmq中的RPC流程如下:

1、首先客户端发送一个reply_to和corrention_id的请求,发布到RPC队列中;

2、服务器端处理这个请求,并把处理结果发布到一个回调Queue,此Queue的名称应当与reply_to的名称一致

3、客户端从回调Queue中得到先前correlation_id设定的值的处理结果。如果碰到和先前不一样的corrention_id的值,将会忽略而不是抛出异常。

对于上面所提到的回调Queue中的消费处理使用的是BasicProperties类;而消息
属性在AMQP的协议中规定有14个;而很多大部分我们没有用到。常用的几个属性有:

  1. Message properties
  2. The AMQP protocol predefine a set of properties that go with a message. Most of the properties are rarely used, with the exception of the following:
  3.  
  4. delivery_mode: Marks a message as persistent (with a value of ) or transient (any other value). You may remember this property from the second tutorial.
  5. content_type: Used to describe the mime-type of the encoding. For example for the often used JSON encoding it is a good practice to set this property to: application/json.
  6. reply_to: Commonly used to name a callback queue.
  7. correlation_id: Useful to correlate RPC responses with requests.

delivery_mode : 标记消息是持久性消息还是瞬态信息。在前面的“Work Queue”中我们已经提到过;

content_type : 用来描述MIME的类型。如把其类型设定为JSON;

reply_to : 用于命名一个回调Queue;

correlation_id : 用于与相关联的请求的RPC响应.

当客户端想要调用服务器的某个方法来完成某项功能时,就可以使用rabbitMQ支持的PRC服务。

其实RPC服务与普通的收发消息的区别不大, RPC的过程其实就是

客户端向服务端定义好的Queue发送消息,其中携带的消息就应该是服务端将要调用的方法的参数 ,并使用Propertis告诉服务端将结果返回到指定的Queue。

示例:

  1. package com.zf.rabbitmq07;
  2.  
  3. import java.io.IOException;
  4.  
  5. import com.rabbitmq.client.AMQP.BasicProperties;
  6. import com.rabbitmq.client.Channel;
  7. import com.rabbitmq.client.Connection;
  8. import com.rabbitmq.client.ConnectionFactory;
  9. import com.rabbitmq.client.ConsumerCancelledException;
  10. import com.rabbitmq.client.QueueingConsumer;
  11. import com.rabbitmq.client.QueueingConsumer.Delivery;
  12. import com.rabbitmq.client.ShutdownSignalException;
  13.  
  14. public class RPCServer {
  15.  
  16. public static final String RPC_QUEUE_NAME = "rpc_queue";
  17.  
  18. public static String sayHello(String name){
  19. return "hello " + name ;
  20. }
  21.  
  22. public static void main(String[] args) throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
  23.  
  24. ConnectionFactory connFac = new ConnectionFactory() ;
  25. connFac.setHost("localhost");
  26.  
  27. Connection conn = connFac.newConnection() ;
  28.  
  29. Channel channel = conn.createChannel() ;
  30.  
  31. channel.queueDeclare(RPC_QUEUE_NAME, false, false, false, null) ;
  32.  
  33. QueueingConsumer consumer = new QueueingConsumer(channel);
  34.  
  35. channel.basicConsume(RPC_QUEUE_NAME, false , consumer) ;
  36.  
  37. while(true){
  38. System.out.println("服务端等待接收消息..");
  39. Delivery deliver = consumer.nextDelivery() ;
  40. System.out.println("服务端成功收到消息..");
  41. BasicProperties props = deliver.getProperties() ;
  42.  
  43. String message = new String(deliver.getBody() , "UTF-8") ;
  44.  
  45. String responseMessage = sayHello(message) ;
  46.  
  47. BasicProperties responseProps = new BasicProperties.Builder()
  48. .correlationId(props.getCorrelationId())
  49. .build() ;
  50.  
  51. //将结果返回到客户端Queue
  52. channel.basicPublish("", props.getReplyTo() , responseProps , responseMessage.getBytes("UTF-8") ) ;
  53.  
  54. //向客户端确认消息
  55. channel.basicAck(deliver.getEnvelope().getDeliveryTag(), false);
  56. System.out.println("服务端返回消息完成..");
  57. }
  58.  
  59. }
  60.  
  61. }
  1. package com.zf.rabbitmq07;
  2.  
  3. import java.io.IOException;
  4. import java.util.UUID;
  5.  
  6. import com.rabbitmq.client.Channel;
  7. import com.rabbitmq.client.Connection;
  8. import com.rabbitmq.client.ConnectionFactory;
  9. import com.rabbitmq.client.ConsumerCancelledException;
  10. import com.rabbitmq.client.QueueingConsumer;
  11. import com.rabbitmq.client.AMQP.BasicProperties;
  12. import com.rabbitmq.client.QueueingConsumer.Delivery;
  13. import com.rabbitmq.client.ShutdownSignalException;
  14.  
  15. public class RPCClient {
  16.  
  17. public static final String RPC_QUEUE_NAME = "rpc_queue";
  18.  
  19. public static void main(String[] args) throws IOException, ShutdownSignalException, ConsumerCancelledException, InterruptedException {
  20.  
  21. ConnectionFactory connFac = new ConnectionFactory() ;
  22. connFac.setHost("localhost");
  23. Connection conn = connFac.newConnection() ;
  24. Channel channel = conn.createChannel() ;
  25.  
  26. //响应QueueName ,服务端将会把要返回的信息发送到该Queue
  27. String responseQueue = channel.queueDeclare().getQueue() ;
  28.  
  29. String correlationId = UUID.randomUUID().toString() ;
  30.  
  31. BasicProperties props = new BasicProperties.Builder()
  32. .replyTo(responseQueue)
  33. .correlationId(correlationId)
  34. .build();
  35.  
  36. String message = "is_zhoufeng";
  37. channel.basicPublish( "" , RPC_QUEUE_NAME , props , message.getBytes("UTF-8"));
  38.  
  39. QueueingConsumer consumer = new QueueingConsumer(channel) ;
  40.  
  41. channel.basicConsume( responseQueue , consumer) ;
  42.  
  43. while(true){
  44.  
  45. Delivery delivery = consumer.nextDelivery() ;
  46.  
  47. if(delivery.getProperties().getCorrelationId().equals(correlationId)){
  48. String result = new String(delivery.getBody()) ;
  49. System.out.println(result);
  50. }
  51.  
  52. }
  53. }
  54.  
  55. }

rabbitMQ学习笔记(七) RPC 远程过程调用的更多相关文章

  1. RabbitMQ入门教程(八):远程过程调用RPC

    原文:RabbitMQ入门教程(八):远程过程调用RPC 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.cs ...

  2. RabbitMQ学习系列(五): RPC 远程过程调用

    前面讲过一些RabbitMQ的安装和用法,也说了说RabbitMQ在一般的业务场景下如何使用.不知道的可以看我前面的博客,http://www.cnblogs.com/zhangweizhong/ca ...

  3. RPC远程过程调用

    什么是RPC: 将一个函数运行在远程计算机上并且等待获取那里的结果,这个称作RPC: (Remote Procedure Call远程过程调用) RPC是一个计算机通信协议. rpc指的是在计算机A上 ...

  4. (扫盲)RPC远程过程调用

    https://blog.csdn.net/mindfloating/article/details/39473807 https://blog.csdn.net/mindfloating/artic ...

  5. openstack学习笔记一 虚拟机启动过程代码跟踪

    openstack学习笔记一 虚拟机启动过程代码跟踪 本文主要通过对虚拟机创建过程的代码跟踪.观察虚拟机启动任务状态的变化,来透彻理解openstack各组件之间的作用过程. 当从horizon界面发 ...

  6. go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer)

    目录 go微服务框架kratos学习笔记七(kratos warden 负载均衡 balancer) demo demo server demo client 池 dao service p2c ro ...

  7. 官网英文版学习——RabbitMQ学习笔记(一)认识RabbitMQ

    鉴于目前中文的RabbitMQ教程很缺,本博主虽然买了一本rabbitMQ的书,遗憾的是该书的代码用的不是java语言,看起来也有些不爽,且网友们不同人学习所写不同,本博主看的有些地方不太理想,为此本 ...

  8. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  9. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

随机推荐

  1. sql系列(基础篇)-前言 课前补充知识

    前言 课前补充知识 Number(p,s) Number(p,s):数字类型,p 表示数字的有效长度(从数字的左边第 1 位不为 0 的開始算起,直到最右边的长度.取值范围 0~38 位),s 表示数 ...

  2. Date and time types

    https://docs.microsoft.com/en-us/sql/t-sql/data-types/date-and-time-types date (Transact-SQL)datetim ...

  3. C - Pocket Book(set)

    Problem description One day little Vasya found mom's pocket book. The book had n names of her friend ...

  4. Winform开发 如何为dataGridView 添加CheckBox列,并获取选中行

    //添加CheckBox列 DataGridViewCheckBoxColumn columncb = new DataGridViewCheckBoxColumn(); columncb.Heade ...

  5. 6 Python+Selenium的元素定位方法(CSS)

    [环境] python3.6+selenium3.0.2+Firefox50.0+win7 [定位方法] 1.方法:find_element_by_css_selector('xx') CSS的语法比 ...

  6. 【技术累积】【点】【java】【1】JSONPath

    闲聊 以后周中每天一篇这种偏短的文章,周末就发长一点的文章,不然自己实在是懒,懒成了习惯了... 开始 首先需要明确的是,这里说的是阿里巴巴的fastjson包中的JSONPath,不是jsonPat ...

  7. AssemblyInfo.cs 文件信息

    using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices ...

  8. eclipse创建maven的ssm项目

    自己接触ssm框架有一段时间了,从最早的接触新版ITOO项目的(SSM/H+Dobbu zk),再到自己近期来学习到的<淘淘商城>一个ssm框架的电商项目.用过,但是还真的没有自己搭建过, ...

  9. Python笔记8----DataFrame(二维)

    目录: DataFrame概念 DataFrame创建 基本操作 查看.索引 修改.删除 统计功能 条件筛选 合并 去除空值 4. 一些常用的函数 apply memory_usage pivot_t ...

  10. MySQL-----笔记3:存储引擎

    1.存储引擎: https://zhidao.baidu.com/question/1049565846666168579.html MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技 ...