实现RPC

首先要弄明白,RPC是个什么东西。

(RPC) Remote Procedure Call Protocol 远程过程调用协议

在一个大型的公司,系统由大大小小的服务构成,不同的团队维护不同的代码,部署在不同的机器。但是在做开发时候往往要用到其它团队的方法,因为已经有了实现。但是这些服务部署不同的机器上,想要调用就需要网络通信,这些代码繁琐且复杂,一不小心就会写的很低效。RPC协议定义了规划,其它的公司都给出了不同的实现。比如微软的wcf,以及现在火热的WebApi。

在RabbitMQ中RPC的实现也是很简单高效的,现在我们的客户端、服务端都是消息发布者与消息接收者。

首先客户端通过RPC向服务端发出请求

我这里有一堆东西需要你给我处理一下,correlation_id:这是我的请求标识,erply_to:你处理完过后把结果返回到这个队列中。

服务端拿到了请求,开始处理并返回

correlation_id:这是你的请求标识 ,原封不动的给你。 这时候客户端用自己的correlation_id与服务端返回的id进行对比。是我的,就接收。

一些繁琐的细节rabbitmq已经为我们封装了,简单的SimpleRpcServer与SimpleRpcClient让Rpc实现的更为方便,这里可以先看一下server端

使用默认的交换机,创建一个SimpleRpcServer的实例,这里需要注意的是,SimpleRpcServer的处理应该是根据业务来的,也就是自己的。在给出的类中没有任何的实现,如果我们创建一个自己的RpcServer并且给出实现

          //创建返回一个新的频道
using (var channel = RabbitMqHelper.GetConnection().CreateModel())
{ //创建一个rpc queue
channel.QueueDeclare("RpcQueue", true, false, false, null); SimpleRpcServer rpc = new SmsSimpleRpcServer(new Subscription(channel, "RpcQueue")); Console.WriteLine("服务端启动成功");
   rpc.MainLoop();
                Console.ReadKey();

            }

这里是自己的一个RpcServer,在HandleSimpleCall方法里返回对处理的回调消息,在ProcessRequest中做出具体的处理逻辑

/// <summary>
/// 发送短信的Rpc
/// </summary>
public class SmsSimpleRpcServer : SimpleRpcServer
{
public SmsSimpleRpcServer(Subscription subscription) : base(subscription)
{
} /// <summary>
/// 执行完成后进行h回调
/// </summary>
/// <param name="isRedelivered"></param>
/// <param name="requestProperties"></param>
/// <param name="body"></param>
/// <param name="replyProperties"></param>
/// <returns></returns>
public override byte[] HandleSimpleCall(bool isRedelivered, IBasicProperties requestProperties, byte[] body, out IBasicProperties replyProperties)
{
replyProperties = null;
return Encoding.UTF8.GetBytes($"给{Encoding.UTF8.GetString(body)}发送短信成功");
} /// <summary>
/// 进行处理
/// </summary>
/// <param name="evt"></param>
public override void ProcessRequest(BasicDeliverEventArgs evt)
{
// todo.....
base.ProcessRequest(evt);
}
}

回到client端,这里的代码也是非常容易的。创建一个SimpleRpcClient,然后指定了交换机类型,因为用的是默认的,所以exchange传的是null, routingkey是我们的rpcqueue。最后调用call方法

using (var channel = RabbitMqHelper.GetConnection().CreateModel())
{
//创建client的rpc
SimpleRpcClient client = new SimpleRpcClient(channel, new PublicationAddress(exchangeType: ExchangeType.Direct, exchangeName: string.Empty, routingKey: "RpcQueue"));
bool flag = true;
var sendmsg = "";
while (flag)
{
Console.WriteLine("请输入要发送的消息");
sendmsg = Console.ReadLine();
if (string.IsNullOrWhiteSpace(sendmsg))
{
Console.Write("请输入消息");
continue;
} var msg = client.Call(Encoding.UTF8.GetBytes(sendmsg)); Console.WriteLine(Encoding.UTF8.GetString(msg)); } Console.ReadKey(); }

把程序运行起来

后面说一些内部的东西,其实上在创建一次SimpleRpcClient的时候都会创建一个回调队列,这个队列在程序关闭后会自动消失,所以这些建议创建一次就够了,都使用这个。如果创建多次会影响性能

在回调的时候,通过源码也可以看到判断了correlation_id的一致性

在server端也可以看到在执行Process后会发布消息到回调队列

RabbitMQ 实现RPC的更多相关文章

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

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

  2. RabbitMQ(四):RPC的实现

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

  3. 基于RabbitMQ的Rpc框架

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

  4. RabbitMQ 笔记-RPC

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

  5. rabbitmq (五)RPC

    Remote Procedure Call or RPC(远程函数调用) 当我们需要在远程计算机上运行一个函数,并且等待结果的时候,我们用到RPC 在rabbitmq客户端使用call函数,发送RPC ...

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

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

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

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

  8. rabbitmq之rpc

    环境:windows或者Linux,python3.6,rabbitmq3.5要求: 可以对指定机器异步的执行多个命令 例子: >>:run "df -h" --hos ...

  9. Python通过RabbitMQ实现RPC

    Client端代码: #!/usr/bin/env python # -*- coding:utf-8 -*- import pika import uuid import time class Fi ...

随机推荐

  1. tomcat 应用部署的几点注意

    将应用部署到Tomcat根目录的目的是可以通过"http://[ip]:[port]"直接访问应用,而不是使用"http://[ip]:[port]/[appName]& ...

  2. break、continue、return

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. ORACLE会话连接进程三者总结

    概念介绍 通俗来讲,会话(Session) 是通信双方从开始通信到通信结束期间的一个上下文(Context).这个上下文是一段位于服务器端的内存:记录了本次连接的客户端机器.通过哪个应用程序.哪个用户 ...

  4. 大数据系列(4)——Hadoop集群VSFTP和SecureCRT安装配置

    前言 经过前三篇文章的介绍,已经通过VMware安装了Hadoop的集群环境,当然,我相信安装的过程肯定遇到或多或少的问题,这些都需要自己解决,解决的过程就是学习的过程,本篇的来介绍几个Hadoop环 ...

  5. MongoDB入门安装

    一.基础信息 系统环境:Linux MongoDB最新版下载:https://codeload.github.com/mongodb/mongo/zip/r3.2.0 二.安装过程 1.将MongoD ...

  6. Centos允许root远程登录设置

      以root权限执行 vi /etc/ssh/sshd_config 将 #PermitRootLogin yes 这一行的“#”去掉,修改为: PermitRootLogin yes 重启ssh服 ...

  7. 使用本地JConsole监控远程JVM(最权威的总结)

    问题背景   Tomcat经常崩溃crash,想看看JVM内存使用情况,就想到了用Jconsole监控,以前只是监控本地的JVM,这次要监控远程的,遇到了不少问题.   经过几个小时的努力,参考了众多 ...

  8. 手动处理datanode磁盘间使用不均的问题

    http://wiki.apache.org/hadoop/FAQ#On_an_individual_data_node.2C_how_do_you_balance_the_blocks_on_the ...

  9. VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。

    早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的.目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少.VB. ...

  10. Bootstrap CSS 栅格、代码和表格

    一.bootstrap栅格 Bootstrap 提供了一套响应式.移动设备优先的流式网格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列. Bootstrap 网格系统(G ...