rabbitmq构造rpc

前言


rpc——remote procedure call 远程调用。在我接触的使用过http协议、thrift框架来实现远程调用。其实消息队列rabbitmq也可以实现。

原理


我们称调用远程服务者为Client,远程服务提供者为Server。

Client充当生产者,将请求发送到rabbitmq队列中,Server作为消费者,处理Client请求产生结果数据result,此刻Server作为生产者,将result

通过rabbitmq队列传递到Client,Client作为结果数据的消费者,得到result。

代码


rpc_client.php

<?php
/**
* Created by PhpStorm.
* User: 王大西
* Date: 2017/10/23
* Time: 16:36
*/
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage; class RpcClient
{
private $connection = null;
private $channel = null;
private $callbackQueue = null;
private $response = null;
private $corrId = null; public function __construct()
{
$this->connection = new AMQPStreamConnection('127.0.0.1', 5672, 'guest', 'guest');
$this->channel = $this->connection->channel(); list($this->callbackQueue, ,) = $this->channel->queue_declare("", false, false, true, false);
$this->channel->basic_consume($this->callbackQueue, '', false, false, false, false, array($this, 'onResponse'));
} public function onResponse($rep)
{
if ($rep->get('correlation_id') == $this->corrId) {
$this->response = $rep->body;
}
} public function call($n)
{
$this->response = null;
$this->corrId = uniqid(); $msg = new AMQPMessage((string) $n, array(
'correlation_id' => $this->corrId,
'reply_to' => $this->callbackQueue
)); $this->channel->basic_publish($msg, '', 'rpc_queue1');
while (!$this->response) {
$this->channel->wait();
}
return intval($this->response);
} } $number = isset($argv[1]) ? $argv[1] : 30;
$objRpcClient = new RpcClient();
$response = $objRpcClient->call($number); echo " RPC result $response\n";

rpc_server.php

<?php
/**
* rpc server
* Created by PhpStorm.
* User: 王大西
* Date: 2017/10/23
* Time: 16:36
*/
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage; $connection = new AMQPStreamConnection('127.0.0.1', 5672, 'guest', 'guest');
$channel = $connection->channel(); $channel->queue_declare('rpc_queue1', false, false, false, false); function fib($n){
if ($n == 0) {
return 0;
}
if ($n == 1) {
return 1;
}
return fib($n-1) + fib($n-2);
} echo " [x] Awaiting RPC requests\n";
$callback = function($req){
$n = intval($req->body);
//todo $n empty return
echo " [.] fib(", $n, ")\n"; $msg = new AMQPMessage((string) fib($n), array('correlation_id' => $req->get("correlation_id")) );
$req->delivery_info['channel']->basic_publish($msg, '', $req->get('reply_to')); $req->delivery_info['channel']->basic_ack($req->delivery_info['delivery_tag']);
}; $channel->basic_qos(null, 1, null);
$channel->basic_consume('rpc_queue1', '', false, false, false, false, $callback); while(count($channel->callbacks)) {
$channel->wait();
} $channel->close();
$connection->close();

测试


server

client

RabbitMq初探——用队列实现RPC的更多相关文章

  1. 【译】RabbitMQ:远程过程调用(RPC)

    在教程二中,我们学习了如何使用工作队列在多个工作线程中分发耗时的任务.但如果我们需要去执行远程机器上的方法并且等待结果会怎么样呢?那又是另外一回事了.这种模式通常被称为远程过程调用(RPC). 本教程 ...

  2. rabbitmq学习(二):rabbitmq(消息队列)的作用以及rabbitmq之直连交换机

    前言 上篇介绍了AMQP的基本概念,组成及其与rabbitmq的关系.了解了这些东西后,下面我们开始学习rabbitmq(消息队列)的作用以及用java代码和rabbitmq通讯进行消息发布和接收.因 ...

  3. RabbitMq初探——消息均发

    消息均发 前言 由前文 RabbitMq初探——消息分发 可知,rabbitmq自带分发机制——消息会按顺序的投放到该队列下的多个消费者,例如1,3,5投放消费者C1,2,4,6投放消费者C2. 这就 ...

  4. RabbitMQ入门(6)——远程过程调用(RPC)

    在RabbitMQ入门(2)--工作队列中,我们学习了如何使用工作队列处理在多个工作者之间分配耗时任务.如果我们需要运行远程主机上的某个方法并等待结果怎么办呢?这种模式就是常说的远程过程调用(Remo ...

  5. RabbitMq初探——安装

    rabbitmq Server安装 rabbitmq server安装很简单. 安装erlang环境 rpm -ihv erlang-18.1-1.el6.x86_64.rpm rpm -ihv ra ...

  6. RabbitMQ (十) 远程过程调用(RPC)

    在远程计算机上运行一个函数并等待结果,我们通常叫这种模式为远程过程调用或者RPC. 通过 RabbitMQ 进行 RPC 很容易,客户端发送请求消息,服务器回复响应消息.为了接收响应,我们需要发送带有 ...

  7. .NET 环境中使用RabbitMQ RabbitMQ与Redis队列对比 RabbitMQ入门与使用篇

    .NET 环境中使用RabbitMQ   在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统时,这种分布式的调用与通信变得越发重要.其次,系统中一般会有很多对实时性要求不高的 ...

  8. RabbitMQ Go客户端教程6——RPC

    本文翻译自RabbitMQ官网的Go语言客户端系列教程,本文首发于我的个人博客:liwenzhou.com,教程共分为六篇,本文是第六篇--RPC. 这些教程涵盖了使用RabbitMQ创建消息传递应用 ...

  9. 如何基于RabbitMQ实现优先级队列

    概述 由于种种原因,RabbitMQ到目前为止,官方还没有实现优先级队列,只实现了Consumer的优先级处理. 但是,迫于种种原因,应用层面上又需要优先级队列,因此需求来了:如何为RabbitMQ加 ...

随机推荐

  1. CentOS装机必备-基本设置以及缺失文件

    主要是虚拟机中安装CentOS每次总会做一些设置,记录下来方便以后. 纯粹基本设置,比如本地SecureCRT可以连接虚拟机中的CentOS. 复杂的非基本设置见:Linux  命令集锦 设置网络 自 ...

  2. 新手C#s.Split(),s.Substring(,)以及读取txt文件中的字符串的学习2018.08.05

    s.split()用于字符串分割,具有多种重载方法,可以通过指定字符或字符串分割原字符串成为字符串数组. //s.Split()用于分割字符串为字符串数组,StringSplitOptions.Rem ...

  3. LMAX系统架构

    本文转载自:LMAX系统架构 ,(非常感谢作者yfx416分享好文) 很多架构师都面临这么一个问题:如何设计一个高吞吐量,低延时的系统?面对这个问题,各位都有自己的答案.但面对这个问题,大家似乎渐渐形 ...

  4. Stop单个Coroutine

    public Coroutine StartCoroutine(string methodName, object value = null); Description Starts a corout ...

  5. 2-ubuntu下访问window的磁盘

    双系统Ubuntu无法进入Windows磁盘的解决方法 有些用户在电脑上安装了Ubuntu和Win10的双系统,正常情况下Ubuntu是可以正常访问Windows磁盘的.但是有些用户就是无法再Ubun ...

  6. juniper交换机配置

    1.链接串口配置: minicom -s ```bash Serial port setup  A -    Serial Device      : /dev/ttyS1               ...

  7. 动态执行SQL语句,接收返回值

    一.exec和sp_executesql介绍 当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句.比如,一个比较通用的分页存储过程,可能需要传入表名,字段,过滤条件, ...

  8. C#的链表操作[数据结构-线性表]

    链式存储结构图解: 上图中,a1,是数据,紧跟着后面的d1是下一个节点的地址值.也就是一个节点的最后存储的是下一个节点的地址值,最后一个节点的存储的下一个地址值是null,代表链表结束. 1,定义链表 ...

  9. Mosquitto服务器的搭建以及SSL/TLS安全通信配置

    Mosquitto服务器的搭建以及SSL/TLS安全通信配置 摘自:https://segmentfault.com/a/1190000005079300 openhab  raspberry-pi ...

  10. CentOS 7 装好系统一些优化

    1.禁用SELINUX vi /etc/sysconfig/selinux  设置为disabled 2.同步时间*/20 * * * * /usr/sbin/ntpdate pool.ntp.org ...