bunny PHP
表现纯PHP AMQP(RABBITMQ)非阻滞ReactPHP库
要求
bunny PHP需要PHP 8.1且更新。
安装
添加为作曲家依赖性:
bunny :@^0.6dev\”>
$ composer require bunny / bunny :@^0.6dev
比较
您可能会询问是否已经没有库/扩展名可以连接到AMQP经纪人(例如RabbitMQ)。是的,有多个选项:
- EXT -AMQP -PHP扩展
- PHP-AMQPLIB-纯PHP AMQP协议实现
- React-AMQP-Ext-AMQP与ReactPHP结合
为什么要选择bunny php?
-
您希望与您一起使用的惯用性PHP API (我在看着您,php-amqplib)。 bunny PHP接口遵循PHP的常见编码标准和命名惯例。参见教程。
-
您不能(不想)安装2014年具有最新稳定版本的PECL扩展程序。BunnyPHP bunny没有像稳定的那样标记。但是它已经在生产中使用。
-
您既具有经典的CLI/FPM和ReactPHP应用程序,又需要连接到RabbitMQ。 bunny PHP带有一个异步客户端,并带有
Fibers同步API。
除了bunny PHP,比主要竞争的图书馆PHP-AMQPLIB更具性能。请参阅benchmark/目录和PHP-AMQPLIB的benchmark/ 。 (对于ext-amp https://gist.**gi*thub.com/wyrihaximus/65fd98e099820aded1b79e9111e02916使用。)
基准运行为:
$ php benchmark/producer.php N & php benchmark/consumer.php
| 图书馆 | n(#消息) | 生产秒 | 产生味精/秒 | 消费秒 | 消耗味精/秒 |
|---|---|---|---|---|---|
| php-amqplib | 100 | 0.000671 | 148998 | 0.001714 | 58343 |
| ext-amqp | 100 | 0.000302 | 331042 | 0.008915 | 11217 |
| bunny PHP | 100 | 0.000194 | 515271 | 0.000939 | 106508 |
| bunny php +/- | +345.8%/+155.6% | +182.5%/+949.5% | |||
| php-amqplib | 1000 | 0.004827 | 207167 | 0.015166 | 65937 |
| ext-amqp | 1000 | 0.002399 | 416846 | 0.078373 | 12760 |
| bunny PHP | 1000 | 0.001597 | 626202 | 0.011139 | 89773 |
| bunny php +/- | +302.2%/+150.2% | +136.1%/+703.5% | |||
| php-amqplib | 10000 | 0.060204 | 166102 | 0.147772 | 67672 |
| ext-amqp | 10000 | 0.022735 | 439853 | 0.754800 | 13249 |
| bunny PHP | 10000 | 0.016441 | 608232 | 0.106685 | 93734 |
| bunny php +/- | +366.1%/+138.2% | +138.5%/+707.4% | |||
| php-amqplib | 100000 | 1.158033 | 90276 | 1.477762 | 67670 |
| ext-amqp | 100000 | 0.952319 | 105007 | 7.494665 | 13343 |
| bunny PHP | 100000 | 0.812430 | 123088 | 1.073454 | 93157 |
| bunny php +/- | +136.3%/+117.2% | +137.6%/+698.1% | |||
| php-amqplib | 1000000 | 18.64132 | 53644 | 18.992902 | 52651 |
| ext-amqp | 1000000 | 12.86827 | 77710 | 89.432139 | 11182 |
| bunny PHP | 1000000 | 11.63421 | 85953 | 11.947426 | 83700 |
| bunny php +/- | +160.2%/+110.6% | +158.9%/+748.5% |
教程
连接
实例化时, bunny PHP Client接受具有连接选项的数组:
bunny\\Client;
use bunny \\Configuration;
$configuration = new Configuration(
host: \’HOSTNAME\’,
vhost: \’VHOST\’, // The default vhost is /
user: \’USERNAME\’, // The default user is guest
password: \’PASSWORD\’, // The default password is guest
);
$ bunny = new Client($configuration);
$ bunny ->connect();\”>
use bunny \\ Client ; use bunny \\ Configuration ; $ configuration = new Configuration ( host: \' HOSTNAME \' , vhost: \' VHOST \' , // The default vhost is / user: \' USERNAME \' , // The default user is guest password: \' PASSWORD \' , // The default password is guest ); $ bunny = new Client ( $ configuration ); $ bunny -> connect ();
使用TLS(/SSL)安全连接
TLS连接的选项应指定为数组tls :
bunny\\Client;
use bunny \\Configuration;
$configuration = new Configuration(
host: \’HOSTNAME\’,
vhost: \’VHOST\’, // The default vhost is /
user: \’USERNAME\’, // The default user is guest
password: \’PASSWORD\’, // The default password is guest
tls: [
\’cafile\’ => \’ca.pem\’,
\’local_cert\’ => \’client.cert\’,
\’local_pk\’ => \’client.key\’,
],
);
$ bunny = new Client($configuration);
$ bunny ->connect();\”>
use bunny \\ Client ; use bunny \\ Configuration ; $ configuration = new Configuration ( host: \' HOSTNAME \' , vhost: \' VHOST \' , // The default vhost is / user: \' USERNAME \' , // The default user is guest password: \' PASSWORD \' , // The default password is guest tls: [ \' cafile \' => \' ca.pem \' , \' local_cert \' => \' client.cert \' , \' local_pk \' => \' client.key \' , ], ); $ bunny = new Client ( $ configuration ); $ bunny -> connect ();
有关选项说明 – 请参阅SSL上下文选项。
注意:无效的TLS配置将导致连接故障。
另请参见常见的配置变体。
提供客户端属性
客户连接可以通过在建立连接时提供可选的client_properties表来显示其功能。
例如,可以通过设置connection_name属性提供连接名称:
bunny\\Client;
use bunny \\Configuration;
$configuration = new Configuration(
host: \’HOSTNAME\’,
vhost: \’VHOST\’, // The default vhost is /
user: \’USERNAME\’, // The default user is guest
password: \’PASSWORD\’, // The default password is guest
clientProperties: [
\’connection_name\’ => \’My connection\’,
],
);
$ bunny = new Client($configuration);
$ bunny ->connect();\”>
use bunny \\ Client ; use bunny \\ Configuration ; $ configuration = new Configuration ( host: \' HOSTNAME \' , vhost: \' VHOST \' , // The default vhost is / user: \' USERNAME \' , // The default user is guest password: \' PASSWORD \' , // The default password is guest clientProperties: [ \' connection_name \' => \' My connection \' , ], ); $ bunny = new Client ( $ configuration ); $ bunny -> connect ();
显然,这可能是动态的,例如,在kubernetes上,您可以包括POD,名称空间和任何其他环境变量:
bunny\\Client;
use bunny \\Configuration;
$configuration = new Configuration(
host: \’HOSTNAME\’,
vhost: \’VHOST\’, // The default vhost is /
user: \’USERNAME\’, // The default user is guest
password: \’PASSWORD\’, // The default password is guest
clientProperties: [
\’connection_name\’ => \’Pod: \’ . getenv(\’POD_NAME\’) . \’; Release: \’ . getenv(\’RELEASE_TAG\’) . \’; Namespace: \’ . getenv(\’POD_NAMESPACE\’),
],
);
$ bunny = new Client($configuration);
$ bunny ->connect();\”>
use bunny \\ Client ; use bunny \\ Configuration ; $ configuration = new Configuration ( host: \' HOSTNAME \' , vhost: \' VHOST \' , // The default vhost is / user: \' USERNAME \' , // The default user is guest password: \' PASSWORD \' , // The default password is guest clientProperties: [ \' connection_name \' => \' Pod: \' . getenv ( \' POD_NAME \' ) . \' ; Release: \' . getenv ( \' RELEASE_TAG \' ) . \' ; Namespace: \' . getenv ( \' POD_NAMESPACE \' ), ], ); $ bunny = new Client ( $ configuration ); $ bunny -> connect ();
发布一条消息
现在,我们已经与服务器有联系,我们需要创建一个频道并声明一个队列以在我们发布消息或为此订阅队列之前进行通信。
bunny->channel();
$channel->queueDeclare(\’queue_name\’); // Queue name\”>
$ channel = $ bunny -> channel (); $ channel -> queueDeclare ( \' queue_name \' ); // Queue name
在带有Quorum队列的虚拟主机上发布消息作为默认
从RabbitMQ 4队列中,将标准定义为Quorum队列,默认情况下是耐用的,以便与它们连接,您应该使用如下的队列声明方法。在当前版本的RabbitMQ 3.11.15中,如果虚拟主机配置为具有默认类型的Quorum,则已经支持这一点。
bunny->channel();
$channel->queueDeclare(\’queue_name\’, false, true); // Queue name\”>
$ channel = $ bunny -> channel (); $ channel -> queueDeclare ( \' queue_name \' , false , true ); // Queue name
通过设置通信渠道,我们现在可以向队列发布一条消息:
$ channel -> publish ( $ message , // The message you\'re publishing as a string [], // Any headers you want to add to the message \'\' , // Exchange name \' queue_name \' , // Routing key, in this example the queue\'s name );
或者:
$ channel -> publish ( body: $ message , // The message you\'re publishing as a string routingKey: \' queue_name \' , // Routing key, in this example the queue\'s name );
订阅队列
订阅队列可以通过两种方式完成。第一种方法将无限期运行:
bunny) {
$success = handleMessage($message); // Handle your message here
if ($success) {
$channel->ack($message); // Acknowledge message
return;
}
$channel->nack($message); // Mark message fail, message will be redelivered
},
\’queue_name\’,
);\”>
$ channel -> run ( static function ( Message $ message , Channel $ channel , Client $ bunny ) { $ success = handleMessage ( $ message ); // Handle your message here if ( $ success ) { $ channel -> ack ( $ message ); // Acknowledge message return ; } $ channel -> nack ( $ message ); // Mark message fail, message will be redelivered }, \' queue_name \' , );
另一种方式使您可以在客户停止之前运行客户的特定时间:
$ channel -> consume (
static function ( Message $ message , Channel $ channel , Client $ client ) {
$ channel -> ack ( $ message ); // Acknowledge message
},
\' queue_name \' ,
);
$ bunny -> run ( 12 ); // Client runs for 12 seconds and then stops
从队列中弹出一条消息
$ message = $ channel -> get ( \' queue_name \' ); // Handle message $ channel -> ack ( $ message ); // Acknowledge message
预摘要计数
使用频道的QoS方法,一种控制bunny php在消费队列时预取多少消息的方法。在下面的示例中,只有5条消息将被预取。结合确认消息,这将变成用于您的应用程序的有效流控制,尤其是异步应用程序。除非已确认,否则不会获取新的消息。
$ channel -> qos ( 0 , // Prefetch size 5 , // Prefetch count );
异步用法
节点:升至版本v0.5.x bunny有两个不同的客户端,一个同步和一个异步。从v0.6开始,两个客户端都将其列入一个:一个具有同步API的异步客户端。
AMQP Interop
bunny库有AMQP Interop兼容包装器。
测试
要充分测试此软件包,需要TLS证书和本地兔子。最重要的是,该项目使用了代码样式修复程序和静态分析。为了使Makefile该项目的任何人都尽可能简单,可以照顾所有这些。
$ make
测试细节
通过运行来创建客户端/服务器TLS证书:
$ cd test/tls && make all && cd -
您需要访问RabbitMQ实例才能运行测试套件。最简单的方法是使用提供的Docker组合设置来创建一个孤立的环境,包括RabbitMQ容器,以运行测试套件。
Docker组成
-
使用Docker组合以创建一个带有RabbitMQ容器和PHP容器来运行测试的网络。项目目录将安装到PHP容器中。
$ docker-compose up -d
要针对不同的TLS配置进行测试(如CI构建),您可以在运行
docker-compose up之前设置环境变量CONFIG_NAME=rabbitmq.tls.verify_none。 -
(可选)使用
docker ps显示运行容器。bunny
[…] bunny _rabbit_node_1_1
[…] bunny _ bunny _1\”>$ docker ps --filter name= bunny [...] bunny _rabbit_node_1_1 [...] bunny _ bunny _1
-
输入PHP容器。
bunny _1 bash\”>
$ docker exec -it bunny _ bunny _1 bash -
在容器中,运行:
$ vendor/bin/phpunit
贡献
-
PHP代码的很大一部分(几乎所有
bunny \\Protocol名称空间中的所有内容)是根据文件spec/amqp-rabbitmq-0.9.1.json生成的。寻找DO NOT EDIT!在文档评论中。更改生成的文件更改
spec/generate.php并运行:$ php ./spec/generate.php
经纪人的兼容性
与RabbitMQ合作良好
不使用ActiveMQ,因为它需要AMQP 1.0,这是完全不同的协议( bunny正在实现AMQP 0.9.1)
执照
bunny PHP已获得MIT许可证的许可。请参阅LICENSE文件。
