实现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. 记录一次Quartz2D学习(一)

    经常看点 drawRect的重写  但是不知道这究竟是神马 今天开始学习这一块的东西,更确切地说是深入 早在view的时候 就经常会调用layer的maskToBounds属性,其实 重写 drawR ...

  2. MVC学习系列5--Layout布局页和RenderSection的使用

    我们开发网站项目的时候,都会遇到这样的问题:就是页面怎么统一风格,有一致的外观,在之前ASP.NET的时代,我们有两种选择,一个是使用MasterPage页,一个是手动,自己在每个页面写CSS样式,但 ...

  3. 运行时报错:java.net.BindException: Address already in use: JVM_Bind <null>:8080 (或8009或8005)

    修改Tomcat端口号步骤:1.找到Tomcat目录下的conf文件夹2.进入conf文件夹里面找到server.xml文件3.打开server.xml文件(打开方式选择记事本)4.在server.x ...

  4. [翻译]——SQL Server使用链接服务器的5个性能杀手

    前言: 本文是对博客http://www.dbnewsfeed.com/2012/09/08/5-performance-killers-when-working-with-linked-server ...

  5. SQLSERVER自动定时(手动)备份工具

    最近项目需要,写了一个小工具软件: 1.实时显示监控 2.可多选择备份数据库 3.按每天定时备份 4.备份文件自动压缩 5.删除之前备份文件 直接上图 1.备份监控界面: 2.数据库设置: 附工具下载 ...

  6. 查看C#的dll所依赖.Net版本

    Microsoft SDK自带的ildasm.exe工具, 是一个反编译工具, 可以查看编译好后的dll的文件 双击ildasm.exe, 把你要识别的.dll文件拖进来, 就会反编译了. 接着在il ...

  7. SCCM 2012 R2安装部署过程和问题(三)

    上篇 SCCM 2012 R2安装部署过程和问题(二) 个人认为对于使用SCCM 2012的最重要的经验是耐心. SCCM采用分布式部署的架构,不同的站点角色可以部署在不同的服务器上,站点角色之间的通 ...

  8. 使用 python 实现 memcached 的启动服务脚本 rc

    #!/usr/bin/python #coding:utf-8 import sys import os from subprocess import Popen, PIPE class Memcac ...

  9. [嵌入式开发]Linux性能分析——上下文切换

    一.从一个问题说起 相信很多人在玩手机还是PC时,都曾碰到过这样一种情况,安装的软件多了系统性能就变慢了,但是去查看CPU利用率一直都低于10%,内存也很充足.我在近期的开发工作中就碰到了类似的情况, ...

  10. 使用ab进行压力测试详解

    ab是apache自带的压力测试工具,非常好用.转载几篇对ab工具的详细使用的博文.猛击下面的链接地址 http://www.365mini.com/page/apache-benchmark.htm ...