RabbitMQ 入门教程(PHP版) 第六部分:远程调用(RPC)
在云计算环境中,很多时候需要用它其他机器的计算资源,把一部分计算任务分配到其他节点来完成。RabbitMQ 如何使用 RPC 呢?下面将会通过其它节点完成斐波纳契示例。
流程图

- 当客户端启动时,它创建了匿名的 callback queue
- 客户端发起 RPC 请求时将同时设置两个 properties:
reply_to
设置为 callback queue;correlation_id
设置为每个请求都是独一无二的值 - 请求将被发送到一个
rpc_queue
队列 - RPC 端或者说 Server 一直在等待那个 queue 的请求,当请求到达时,它将通过在
reply_to
指定的 queue 回复一个 Message 给客户端 - client 一直等待 callback queue 的数据,当 Message 到达时,它将检查
correlation_id
的值,如果值和它 request 发送时的一致那么就将返回响应
整合代码
rpc_client.php
<?php /**
* RPC客户端
*/
$routing_key = 'rpc_queue';
$num = empty($argv[1]) ? 0 : intval($argv[1]); // 建立TCP连接
$connection = new AMQPConnection([
'host' => 'localhost',
'port' => '5672',
'vhost' => '/',
'login' => 'guest',
'password' => 'guest'
]);
$connection->connect() or die("Cannot connect to the broker!\n"); $channel = new AMQPChannel($connection); $client_queue = new AMQPQueue($channel);
$client_queue->setFlags(AMQP_EXCLUSIVE);
$client_queue->declareQueue();
$callback_queue_name = $client_queue->getName(); $corr_id = uniqid();
$properties = [
'correlation_id' => $corr_id,
'reply_to' => $callback_queue_name
]; $exchange = new AMQPExchange($channel);
$exchange->publish($num, $routing_key, AMQP_NOPARAM, $properties); $client_queue->consume(function($envelope, $queue) use ($corr_id){
if ($envelope->getCorrelationId() == $corr_id) {
$msg = $envelope->getBody();
var_dump('Received Data: ' . $msg);
$queue->nack($envelope->getDeliveryTag());
return false;
}
}); // 断开连接
$connection->disconnect();
rpc_server.php
<?php /**
* RPC服务端
*/
$routing_key = 'rpc_queue'; // 建立TCP连接
$connection = new AMQPConnection([
'host' => 'localhost',
'port' => '5672',
'vhost' => '/',
'login' => 'guest',
'password' => 'guest'
]);
$connection->connect() or die("Cannot connect to the broker!\n"); $channel = new AMQPChannel($connection);
$channel->setPrefetchCount(1); $server_queue = new AMQPQueue($channel);
$server_queue->setName($routing_key);
$server_queue->declareQueue(); $exchange = new AMQPExchange($channel); $server_queue->consume(function($envelope, $queue) use ($exchange){
$num = intval($envelope->getBody());
$response = fib($num);
$exchange->publish($response, $envelope->getReplyTo(), AMQP_NOPARAM, [
'correlation_id' => $envelope->getCorrelationId(),
]);
$queue->ack($envelope->getDeliveryTag());
}); // 断开连接
$connection->disconnect(); // 斐波那契函数
function fib($num) {
if ($num == 0)
return 1;
else if ($num == 1)
return 1;
else
return fib($num - 1) + fib($num - 2);
}
先运行脚本:
php rpc_server.php
再运行另外的脚本:
php rpc_client.php 1
php rpc_client.php 5
php rpc_client.php 15
php rpc_client.php 20
效果展示:
RabbitMQ 入门教程(PHP版) 第六部分:远程调用(RPC)的更多相关文章
- RabbitMQ 入门教程(PHP版) 第三部分:发布/订阅(Publish/Subscribe)
发布/订阅 在上篇第二部分教程中,我们搭建了一个工作队列.每个任务之分发给一个工作者(worker).在本篇教程中,我们要做的之前完全不一样——分发一个消息给多个消费者(consumers).这种模式 ...
- RabbitMQ 入门教程(PHP版) 第二部分:工作队列(Work queues)
工作队列 在第一篇教程中,我们已经写了一个从已知队列中发送和获取消息的程序.在这篇教程中,我们将创建一个工作队列(Work Queue),它会发送一些耗时的任务给多个工作者(Works ). 工作队列 ...
- RabbitMQ 入门教程(PHP版) 第一部分:Hello World
abbitMQ是一个消息代理.它的核心原理非常简单:接收和发送消息.你可以把它想像成一个邮局:你把信件放入邮箱,邮递员就会把信件投递到你的收件人处.在这个比喻中,RabbitMQ是一个邮箱.邮局.邮递 ...
- RabbitMQ 入门教程(PHP版) 使用rabbitmq-delayed-message-exchange插件实现延迟功能
延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...
- RabbitMQ 入门教程(PHP版) 延迟队列,延迟任务
延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...
- RabbitMQ 入门教程(PHP版) 简单Demo
RabbitMQ的关键字说明 (1)Broker:经纪人.提供一种传输服务,维护一条从生产者到消费者的传输线路,保证消息数据能按照指定的方式传输.粗略的可以将图中的RabbitMQ Server当作B ...
- RabbitMQ 入门教程(PHP版) 第四部分:路由(Routing)
路由(Routing) 在前面的第三部分教程中,我们实现了一个简单的日志系统.可以把日志消息广播给多个接收者. 本篇教程中我们打算新增一个功能——使得它能够只订阅消息的一个字集.例如,我们只需要把严重 ...
- 转 RabbitMQ 入门教程(PHP版) 使用rabbitmq-delayed-message-exchange插件实现延迟功能
延迟任务应用场景 场景一:物联网系统经常会遇到向终端下发命令,如果命令一段时间没有应答,就需要设置成超时. 场景二:订单下单之后30分钟后,如果用户没有付钱,则系统自动取消订单. 场景三:过1分钟给新 ...
- RabbitMQ 入门教程(PHP版) 第五部分:通过主题进行消息分发(Topics)
对于 Message 的 routing_key 字符串格式是有限制的:以点号"."分割的字符表,如php.laravel,并且长度不能超过 255 个字节. 对于 routing ...
随机推荐
- 安装 uwsgi报错解决
背景: 安装 uwsgi时报错如下,查阅相关资料说是 python-devel的问题,于是安装之后python-devel后问题解决 报错如下: (venv) [xxxxxxx]# pip insta ...
- Linux中修改环境变量
<1>Linux 的变量作用范围可分为两类:环境变量和本地变量 环境变量,或者称为全局变量,存在与所有的shell 中,在你登陆系统的时候就已经有了相应的系统定义的环境变量了.Linux ...
- Oracle-分析函数之排序值rank()和dense_rank()
聚合函数RANK 和 dense_rank 主要的功能是计算一组数值中的排序值. 在9i版本之前,只有分析功能(analytic ),即从一个查询结果中计算每一行的排序值,是基于order_by_cl ...
- mui 点击长按复制文本
项目需要长按复制文本内容,由于也没仔细研究过 mui 所以就直接百度.看到了 花落乱了流年 这篇博客 我就把这个博客的代码融合到自己的项目里,实现了复制的需求 直接上代码 单独写到了一个 js 文件. ...
- Codeforces Round #604 (Div. 2) E. Beautiful Mirrors
链接: https://codeforces.com/contest/1265/problem/E 题意: Creatnx has n mirrors, numbered from 1 to n. E ...
- HDU - 4352 - XHXJ's LIS(数位DP)
链接: https://vjudge.net/problem/HDU-4352 题意: a 到 b中一个数组成递增子序列长度等于k的数的个数 思路: 因为只有10个数,使用二进制维护一个递增序列,每次 ...
- php流程控制 之循环语句的使用
循环语句的使用 王同学需要反复往返于北京和大连,就是典型的循环结构.假设王思总投资这个项目需要往返大连100次,每次往返都王同学都会计数一次.难道我们写一百遍同样的代码?显然对于智商极高的程序员来说不 ...
- 97: cf 983E 倍增+树套树
$des$一棵 $n$ 个点的树,树上有 $m$ 条双向的公交线路,每条公交线路都在两个节点之间沿最短路径往返.$q$ 次询问从一个点要到达另一个点,在只坐公交的情况下,至少需要坐几辆公交车:或者判断 ...
- 如何快速把ps序列图层建立帧动画?
工具ps 1.将序列帧图片载入ps 新建->脚本->将文件载入堆栈 2.制作序列帧动画 窗口->时间轴->时间轴面板右上角菜单->从图层建立帧 3.去除多余的透明画布 全 ...
- jenkins之SSH Publishers环境变量
我使用的是docker部署jenkins,使用172.16.1.245作为部署服务器. 1.问题 在SSH Publishers里执行的环境变量,不是ssh server主机设置的环境变量,这样会导致 ...