bunny/bunny

高性能纯PHP AMQP (RabbitMQ) 非阻塞 ReactPHP 库

v0.5.5 2023-08-01 19:34 UTC

README

Build Status Downloads this Month Latest stable

高性能纯PHP AMQP (RabbitMQ) 同步/异步 (ReactPHP) 库

要求

BunnyPHP 需要 PHP 7.1 及以上版本。

安装

将 BunnyPHP 添加为 Composer 依赖项

$ composer require bunny/bunny:@dev

比较

您可能会问,是否已经存在用于连接 AMQP 代理(例如 RabbitMQ)的库/扩展。是的,有多个选项

为什么您要选择 BunnyPHP 呢?

  • 您想要一个与 (我看着您,php-amqplib) 一起使用的 良好的 PHP 风格 API。BunnyPHP 的接口遵循 PHP 的通用 编码标准和命名规范。请参阅教程。

  • 不能(不想)安装 2014 年以来一直具有最新稳定版本的 PECL 扩展。BunnyPHP 尚未标记为稳定。但它已经在生产中使用。

  • 您同时拥有 经典 CLI/FPM 和 ReactPHP 应用程序,并需要连接到 RabbitMQ。BunnyPHP 包含具有相同 PHP-idiomatic 接口的同时和异步客户端。异步客户端使用 react/promise

除此之外,BunnyPHP 比主要的竞争库 php-amqplib 性能更好。请参阅 benchmark/ 目录php-amqplib 的 benchmark/

基准测试以以下方式进行

$ php benchmark/producer.php N & php benchmark/consumer.php

教程

连接

在实例化 BunnyPHP Client 时,可以接受一个包含连接选项的数组

$connection = [
    '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($connection);
$bunny->connect();

使用 SSL/TLS 连接

SSL 连接的选项应指定为 ssl 数组

$connection = [
    'host'      => 'HOSTNAME',
    'vhost'     => 'VHOST',    // The default vhost is /
    'user'      => 'USERNAME', // The default user is guest
    'password'  => 'PASSWORD', // The default password is guest
    'ssl'       => [
        'cafile'      => 'ca.pem',
        'local_cert'  => 'client.cert',
        'local_pk'    => 'client.key',
    ],
];

$bunny = new Client($connection);
$bunny->connect();

有关选项的描述,请参阅 SSL 上下文选项

注意:无效的 SSL 配置会导致连接失败。

另请参阅 常见的配置变体

提供客户端属性

客户端连接可以通过在建立连接时提供一个可选的 client_properties 表来向服务器展示其功能。

例如,可以通过设置 connection_name 属性 来提供连接名称

$connection = [
    'host'              => 'HOSTNAME',
    'vhost'             => 'VHOST',    // The default vhost is /
    'user'              => 'USERNAME', // The default user is guest
    'password'          => 'PASSWORD', // The default password is guest
    'client_properties' => [
        'connection_name' => 'My connection',
    ],
];

$bunny = new Client($connection);
$bunny->connect();

发布消息

现在我们已经与服务器建立了连接,我们需要创建一个通道并声明一个队列,以便在发布消息之前进行通信,或者订阅该队列。

$channel = $bunny->channel();
$channel->queueDeclare('queue_name'); // Queue name

在默认的具有法定人数队列的虚拟主机上发布消息

从RabbitMQ 4开始,4个队列将默认定义为仲裁队列,这些队列默认是持久的。为了连接到它们,您应该使用以下队列声明方法。在当前版本的RabbitMQ 3.11.15中,这已经得到支持,如果虚拟主机配置为默认类型为仲裁队列。

$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->run(
    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(
    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方法,可以控制BunnyPHP在消费队列时预取多少条消息。在下面的示例中,只预取5条消息。结合确认消息,这将成为您应用程序的有效流量控制,特别是异步应用程序。除非确认了一条消息,否则不会获取新消息。

$channel->qos(
    0, // Prefetch size
    5  // Prefetch count
);

异步使用

节点:在版本 v0.5.x 之前,Bunny有两个不同的客户端,一个是同步客户端,另一个是异步客户端。从 v0.6 开始,两个客户端都被合并到一个:一个具有同步API的异步客户端。

AMQP互操作性

对于bunny库,有amqp互操作性兼容的包装器。

测试

通过以下命令创建客户端/服务器SSL证书

$ cd test/ssl && make all && cd -

您需要访问RabbitMQ实例才能运行测试套件。最简单的方法是使用提供的Docker Compose设置来创建一个隔离的环境,包括RabbitMQ容器,以便在其中运行测试套件。

Docker Compose

  • 使用Docker Compose创建一个网络,包括一个RabbitMQ容器和一个PHP容器,以运行测试。项目目录将被挂载到PHP容器中。

    $ docker-compose up -d
    

    要测试不同的SSL配置(例如CI构建),在运行 docker-compose up 之前,您可以设置环境变量 CONFIG_NAME=rabbitmq.ssl.verify_none

  • 可选地使用 docker ps 显示正在运行的容器。

    $ docker ps --filter name=bunny
    [...] bunny_rabbit_node_1_1
    [...] bunny_bunny_1
    
  • 进入PHP容器。

    $ docker exec -it bunny_bunny_1 bash
    
  • 在容器内,运行

    $ vendor/bin/phpunit
    

贡献

  • PHP代码的大部分(几乎在 Bunny\Protocol 命名空间中的所有内容)都是从文件 spec/amqp-rabbitmq-0.9.1.json 中的spec生成的。在文档注释中查找 DO NOT EDIT!

    要更改生成的文件,更改 spec/generate.php 并运行

    $ php ./spec/generate.php

代理兼容性

与RabbitMQ兼容良好

由于它需要AMQP 1.0(这是一个完全不同的协议,Bunny正在实现AMQP 0.9.1),因此不与ActiveMQ兼容

许可

BunnyPHP遵循MIT许可协议。请参阅 LICENSE 文件。