Remote Procedure Call or RPC(远程函数调用)

当我们需要在远程计算机上运行一个函数,并且等待结果的时候,我们用到RPC

在rabbitmq客户端使用call函数,发送RPC请求并阻塞等待结果返回.

提示:虽然RPC是一个很好计算处理的常见模式,但是有时程序员无法判断

一个函数调用时一个本地调用还是一个缓慢的RPC调用.所以有很多错误的不可预知的结果.

并且增加调试的复杂性.

有三个建议:

1.确定函数调用时本地还是远程调用.

2.给系统添加文档,确定各个组件之间的依赖

3.处理每个RPC调用过程中的异常,

callback queue

因为通常订阅/发布是一个单向过程,只需要一个队列,但是在RPC调用的时候需要制定两个队列,一个发送,一个接受结果.所以用ReplyTo属性指定接受结果队列名称.

correlation Id

为每一个RPC调用创建一个callback queue是低效的,所以可以使用一个公用的callback queue使用关联id来标识每个请求.

源码:

客户端

public class RpcClient
{
private readonly IConnection connection;
private readonly IModel channel;
private readonly string replyQueueName;
private readonly EventingBasicConsumer consumer;
private readonly BlockingCollection<string> respQueue = new BlockingCollection<string>();
private readonly IBasicProperties props; public RpcClient()
{
var factory = new ConnectionFactory() { HostName = "your ip", UserName = "your name", Password = "your pwd" }; connection = factory.CreateConnection();
channel = connection.CreateModel();
replyQueueName = channel.QueueDeclare().QueueName;
consumer = new EventingBasicConsumer(channel); props = channel.CreateBasicProperties();
var correlationId = Guid.NewGuid().ToString();
props.CorrelationId = correlationId;
props.ReplyTo = replyQueueName; consumer.Received += (model, ea) =>
{
var body = ea.Body;
var response = Encoding.UTF8.GetString(body);
if (ea.BasicProperties.CorrelationId == correlationId)
{
respQueue.Add(response);
}
};
} public string Call(string message)
{
var messageBytes = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(
exchange: "",
routingKey: "rpc_queue",
basicProperties: props,
body: messageBytes); channel.BasicConsume(
consumer: consumer,
queue: replyQueueName,
autoAck: true); return respQueue.Take(); ;
} public void Close()
{
connection.Close();
}
}
class Program
{
static void Main(string[] args)
{
var rpcClient = new RpcClient(); Console.WriteLine(" [x] Requesting fib(30)");
var response = rpcClient.Call(""); Console.WriteLine(" [.] Got '{0}'", response);
rpcClient.Close();
}
}

服务端:

public static void Main()
{
var factory = new ConnectionFactory() { HostName = "your ip", UserName = "your name", Password = "your pwd" };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: "rpc_queue", durable: false,
exclusive: false, autoDelete: false, arguments: null);
channel.BasicQos(, , false);
var consumer = new EventingBasicConsumer(channel);
channel.BasicConsume(queue: "rpc_queue",
autoAck: false, consumer: consumer);
Console.WriteLine(" [x] Awaiting RPC requests"); consumer.Received += (model, ea) =>
{
string response = null; var body = ea.Body;
var props = ea.BasicProperties;
var replyProps = channel.CreateBasicProperties();
replyProps.CorrelationId = props.CorrelationId; try
{
var message = Encoding.UTF8.GetString(body);
int n = int.Parse(message);
Console.WriteLine(" [.] fib({0})", message);
response = fib(n).ToString();
}
catch (Exception e)
{
Console.WriteLine(" [.] " + e.Message);
response = "";
}
finally
{
var responseBytes = Encoding.UTF8.GetBytes(response);
channel.BasicPublish(exchange: "", routingKey: props.ReplyTo,
basicProperties: replyProps, body: responseBytes);
channel.BasicAck(deliveryTag: ea.DeliveryTag,
multiple: false);
}
}; Console.WriteLine(" Press [enter] to exit.");
Console.ReadLine();
}
} /// /// Assumes only valid positive integer input.
/// Don't expect this one to work for big numbers, and it's
/// probably the slowest recursive implementation possible.
/// private static int fib(int n)
{
if (n == || n == )
{
return n;
} return fib(n - ) + fib(n - );
}

rabbitmq (五)RPC的更多相关文章

  1. RabbitMQ(四):RPC的实现

    原文:RabbitMQ(四):RPC的实现 一.RPC RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. ...

  2. RabbitMQ 实现RPC

    实现RPC 首先要弄明白,RPC是个什么东西. (RPC) Remote Procedure Call Protocol 远程过程调用协议 在一个大型的公司,系统由大大小小的服务构成,不同的团队维护不 ...

  3. RabbitMQ中RPC的实现及其通信机制

    RabbitMQ中RPC的实现:客户端发送请求消息,服务端回复响应消息,为了接受响应response,客户端需要发送一个回调队列的地址来接受响应,每条消息在发送的时候会带上一个唯一的correlati ...

  4. 基于RabbitMQ的Rpc框架

    参考文档:https://www.cnblogs.com/ericli-ericli/p/5917018.html 参考文档:RabbitMQ 实现RPC MQ的使用场景大概包括解耦,提高峰值处理能力 ...

  5. RabbitMQ除开RPC的五种消模型----原生API

    2.五种消息模型 RabbitMQ提供了6种消息模型,但是第6种其实是RPC,并不是MQ,因此不予学习.那么也就剩下5种. 但是其实3.4.5这三种都属于订阅模型,只不过进行路由的方式不同. 通过一个 ...

  6. RabbitMQ 笔记-RPC

    RabbitMQ中实现RPC的机制是: 客户端发送请求(消息)时,在消息的属性(MessageProperties,在AMQP协议中定义了14中properties,这些属性会随着消息一起发送)中设置 ...

  7. RabbitMQ、RPC、SaltStack "贡"具的使用

    消息队列 使用队列的场景 在程序系统中,例如外卖系统,订单系统,库存系统,优先级较高 发红包,发邮件,发短信,app消息推送等任务优先级很低,很适合交给消息队列去处理,以便于程序系统更快的处理其他请求 ...

  8. rabbitmq五种消息模型整理

    目录 0. 配置项目 1. 基本消息模型 1.1 生产者发送消息 1.2 消费者获取消息(自动ACK) 1.3 消息确认机制(ACK) 1.4 消费者获取消息(手动ACK) 1.5 自动ACK存在的问 ...

  9. RabbitMQ 五种工作模式

    官网介绍:https://www.rabbitmq.com/getstarted.html 五种工作模式的主要特点 简单模式:一个生产者,一个消费者 work模式:一个生产者,多个消费者,每个消费者获 ...

随机推荐

  1. Golang微服务:Micro限流、熔断

    Wrapper Wrapper提供了一种包装机制,使得在执行某方法前先执行Wrapper,优点Filter的意思:因此可以在客户端和服务器做很多功能:熔断限流.Filter.Auth等. client ...

  2. Jdbc来操作事物 完成模拟银行的转账业务

    创建JDBC工具类 package cn.aa4_2.JDBCUtils; import java.io.FileReader; import java.io.IOException; import ...

  3. Linux 的终端及设置

    Linux 的终端及设置 终端是一种字符型设备,有多种类型,通常使用tty 来简称各种类型的终端设备.终端特殊设备文件一般有以下几种: /dev/ttySn 串行端口终端 (Serial Port T ...

  4. vue day5 分页控件

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. (转)薛飞 基于VLC的Unity视频播放器(二)

    转自:http://www.manew.com/thread-144229-1-1.html 留个记录.

  6. git 分支管理记录

    测试环境 :虚拟机(VMware Fusion Centos 6.5) 1.安装git环境 [root@localhost ~]# yum -y install git 2.检测git是否安装成功 [ ...

  7. 转载 JAVA gc垃圾回收机制

    thanks:https://m.oschina.net/u/123553 一.GC概要 JVM堆相关知识    为什么先说JVM堆?    JVM的堆是Java对象的活动空间,程序中的类的对象从中分 ...

  8. macbook远程连接报错no matching cipher found

    在.ssh/目录下添加config文件 Host xxx.xxx.xxx.xxx Ciphers 3des-cbc KexAlgorithms +diffie-hellman-group1-sha1 ...

  9. layui 表格组件不能访问连续的属性的解决办法

    table.js里第741行改成这样,它这里只能访问一级属性// var content = item1[field]; 不能访问对象内的对象,比如item1.depart.name,只能访问一级属性 ...

  10. 当yum安装出现Error: Package: glibc-headers .....时

    环境 CentOS Linux release 7.4.1708 (Core)   当使用yum源安装时,出现以下报错 Error: Package: glibc-headers-.el7_4..x8 ...