在上次学xattr的时候用它简单实现一个中间件,我去了解了一下rabbitmq这个消息中间件,感觉理论上还是挺好用的,给一般并发量的系统用足够了。

首先安装这个服务。

sudo apt search rabbitmq

发现了这个

rabbitmq-server/focal-updates,focal-updates,focal-security,focal-security,now 3.8.2-0ubuntu1.3 all
AMQP server written in Erlang

好,然后安装它

sudo apt-get install rabbitmq-server

等他跑完就行了,要用PHP调用的话需要这个php组件

composer require php-amqplib/php-amqplib

跑完后创建两个文件 receive.php 和 send.php

receive.php

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection; $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);
echo ' [*] waiting for message. ctrl+c to stop', "\n";
$callback = function($msg) {
echo " [x] Received " . $msg->body . "\n";
};
$channel->basic_consume('hello', '', false, true, false, false, $callback);
while (count($channel->callbacks)) {
$channel->wait();
}
$channel->close();
$connection->close();

send.php

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage; $start_time = microtime(true); $connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('hello', false, false, false, false);
$msg = new AMQPMessage('Hello world!');
$channel->basic_publish($msg, '', 'hello');
// echo " [x] Send 'Hello world'\n";
$channel->close();
$connection->close(); $end_time = microtime(true); echo "use time " . ($end_time - $start_time) * 1000 . " ms \n";

先运行 php receive.php 它就一直在监听消息

[*] waiting for message. ctrl+c to stop

再运行 php send.php 进行投递消息

就可以看到效果了。

 [*] waiting for message. ctrl+c to stop
[x] Received Hello world!

关于这个例子 这篇文章介绍了很详细 https://www.rabbitmq.com/tutorials/tutorial-one-php.html

git仓库在这里 https://github.com/php-amqplib/php-amqplib

除了这个composer之外 还可以安装PHP的扩展

sudo apt-get install php7.4-amqp

安装后用  php -m |grep amqp 来验证一下扩展是不是真的安装上了。

如果我不运行receive.php 直接运行send.php会怎么样呢?

我发现它会把消息堆积放在中间介质里面(当然这个应该是rabbitmq server服务里面的一部分)

只运行 send.php 不运行receive.php 发现有消息堆积 我们可以用  sudo rabbitmqctl list_queues 来查看列表

sudo rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
name messages
hello 3

我执行了send.php3次留下来3条消息,在仓库列表里面等待处理。

此时再运行receive.php 然后进来就有消息输出 再看看列表,发现没有消息堆积了

sudo rabbitmqctl list_queues
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
name messages
hello 0

这说明生产者是可以随时生产投递到中间存储的,消费者启动的时候会自己去消费堆积任务。
如果生产者消费者都在运行,那么生产者投递的消息马上就被消费者处理了。

当你运行两个receive.php的话

然后让 send.php 执行10个消息投递

for ($i=0; $i < 10; $i++) {
$msg = new AMQPMessage('Hello world!'.$i);
$channel->basic_publish($msg, '', 'hello');
}

1个消费者打印

[*] waiting for message. ctrl+c to stop
[x] Received Hello world!0
[x] Received Hello world!2
[x] Received Hello world!4
[x] Received Hello world!6
[x] Received Hello world!8

另1个消费者打印

[*] waiting for message. ctrl+c to stop
[x] Received Hello world!1
[x] Received Hello world!3
[x] Received Hello world!5
[x] Received Hello world!7
[x] Received Hello world!9

看来它俩分配了消息

然后对于这个效率的话,我做了一个测试

投递   1 万条消息耗费   228 ms 合约 43859 条/秒
投递 10 万条消息耗费 1512 ms 合约 66137 条/秒
投递 100 万条消息耗费 18785 ms 合约 54990 条/秒
for ($i=0; $i < 10000; $i++) {
$msg = new AMQPMessage('Hello world!'.$i);
$channel->basic_publish($msg, '', 'hello');
}
for ($i=0; $i < 100000; $i++) {
$msg = new AMQPMessage('Hello world!'.$i);
$channel->basic_publish($msg, '', 'hello');
}
for ($i=0; $i < 1000000; $i++) {
$msg = new AMQPMessage('Hello world!'.$i);
$channel->basic_publish($msg, '', 'hello');
}

可以看出这个投递极限也就是单个进程每秒5-6万条左右,总体而言效率还算不错,已经能满足很多系统了,毕竟业务上也没有那么多消息要传递,如果非要更快,那就需要考虑用更快的xattr或者共享内存之类的了。

rabbitmq消息中间件的初步探索的更多相关文章

  1. NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索

    一.主从复制架构简介 通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构.那么,我们首先来了解一 ...

  2. 【转】 NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索

    一.主从复制架构简介 通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构.那么,我们首先来了解一 ...

  3. spring boot / cloud (九) 使用rabbitmq消息中间件

    spring boot / cloud (九) 使用rabbitmq消息中间件 前言 rabbitmq介绍: RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统.它可以用于大型软件系统 ...

  4. 企查查app 初步探索

    企查查app sign算法破解初步探索 之前有说过企查查的sign的解密,但这次是企查查app的sign算法破解,目前是初步进程. 已删除!!!! 上边一些变量已经找到了,其中就有时间戳,其余两个需要 ...

  5. Springboot与ActiveMQ、Solr、Redis中分布式事物的初步探索

    Springboot与ActiveMQ.Solr.Redis中分布式事物的初步探索 解决的场景:事物中的异步问题,当要求数据库与solr服务器的最终一致时. 程序条件: 利用消息队列,当数据库添加成功 ...

  6. rabbitmq介绍以及初步使用

    什么是MQ? ​ MQ(Message Queue):翻译为消息队列,通过典型的生产者和消费者模型,生产者不断向消息队列中生产消息,消费者不断地从队列中获取消息.因为消息的生产和消费都是异步的,而且只 ...

  7. RabbitMQ 消息中间件

    RabbitMQ 是使用 Erlang 语言开发的消息中间件, 其遵循了高级消息队列协议(Advanced Message Queuing Protocol, AMQP). 与 Kafka 等消息队列 ...

  8. CentOS6.8搭建rabbitmq消息中间件

    参考资料:http://blog.csdn.net/yunfeng482/article/details/72853983 一.rabbitmq简介 MQ全称为Message Queue, 消息队列( ...

  9. python中使用rabbitmq消息中间件

    上周一直在研究zeromq,并且也实现了了zeromq在python和ruby之间的通信,但是如果是一个大型的企业级应用,对消息中间件的要求比较高,比如消息的持久化机制以及系统崩溃恢复等等需求,这个时 ...

  10. RabbitMQ消息中间件的用法

    1.什么是RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然在同步消 ...

随机推荐

  1. 去除WinForm程序中的Devexpress弹窗

    去除WinForm程序中的Devexpress弹窗 /// <summary> /// 应用程序的主入口点. /// </summary> [STAThread] static ...

  2. 设计模式 | 中介者模式/调停者模式(Mediator)

    定义: 用一个中介对象来封装以系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地变化他们之间的交互. 结构:(书中图,侵删) 一个抽象中介者 若干具体中介者 一个抽象 ...

  3. Java Swing Loading转圈的进度提示框

    Java Swing Loading转圈的进度提示框 具体只需要两个类 AnimatedPanel.java InfiniteProgressPanel.java 前因:我们开发的web应用,有个奇葩 ...

  4. Blender - 动画demo体后感

    Blender 一个非常不错的免费的3D.2D软件 超级不错 我初步的按照网上的动画教程,做了一个很简单的 不断跳动的独眼球 为什么独眼?一开始我是画了两个眼睛,结果最后总是出了点问题,没有办法cop ...

  5. TS中的声明文件

    TS中的声明文件 .d.ts 的作用是为了在TS中使用js文件,但是js文件没有类型,ts又是一个类型严格的语言.所以为了在ts中使用js第三方包,或者自定义Js模块.便由此引出了.d.ts文件. 需 ...

  6. 个头小却很能“打”!合合信息扫描全能王推出A4便携式打印机

    个头小却很能"打"!合合信息扫描全能王推出A4便携式打印机   过去,为了打印一份清晰工整的材料,人们往往需要到专门的打印店或办公室.处理文件.对于销售.物流人员.工程师.医生.媒 ...

  7. CSS – Design System

    介绍 这篇 Tailwind CSS 的教程:Translating a Custom Design System to Tailwind CSS 充分的体现了什么是 Design System. 设 ...

  8. ASP.NET Core C# 反射 & 表达式树 (第三篇)

    前言 前一篇讲完了反射, 这一篇来讲一下和反射息息相关的表达式树. 首先搞清楚 Delegate, Action, Func, Anonymous Method, Lambda, Expression ...

  9. Flutter Engage China 开发者常见问题解答 | 上篇

    再次感谢大家对 Flutter Engage China 活动 的关注和积极参与!我们在活动前后收到了很多来自开发者的反馈和问题,Flutter 团队和演讲嘉宾在直播 Q&A 环节中也针对部分 ...

  10. 提升软件测试效率与灵活性:探索Mock测试的重要性

    Mock测试是测试过程中的一种方法,用于替代那些难以构造或获取的对象,通过创建虚拟对象来进行测试.所谓难以构造的对象如何理解呢? 举例来说,像HttpServletRequest这样的对象需要在具有s ...