高效的纯PHP AMQP(RabbitMQ)同步/异步(ReactPHP)库

v0.5.5.1 2024-01-02 10:48 UTC

This package is auto-updated.

Last update: 2024-08-31 00:54:19 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 风格 API 来与之交互(我指的是 php-amqplib)。BunnyPHP 接口遵循 PHP 的常见 编码标准和命名约定。请参阅教程。

  • 你不能(不想)安装 PECL 扩展,该扩展的最新稳定版本发布于 2014 年。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 配置将导致连接失败。

另请参阅 常见配置变体

发布一条消息

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

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

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

从 RabbitMQ 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

预取计数

控制BunnyPHP在消费队列时预取消息数量的方法是通过使用通道的QOS方法。以下示例中,只会预取5条消息。结合消息的确认,这可以成为您应用程序的有效流控制,特别是对异步应用程序。除非有消息被确认,否则不会获取新消息。

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

异步使用

Bunny支持使用ReactPHP进行同步和异步使用。以下示例展示了如何设置客户端并无限期地消费队列。

(new Async\Client($eventLoop, $options))->connect()->then(function (Async\Client $client) {
   return $client->channel();
})->then(function (Channel $channel) {
   return $channel->qos(0, 5)->then(function () use ($channel) {
       return $channel;
   });
})->then(function (Channel $channel) use ($event) {
   $channel->consume(
       function (Message $message, Channel $channel, Async\Client $client) use ($event) {
           // Handle message

           $channel->ack($message);
       },
       'queue_name'
   );
});

AMQP互操作

为bunny库提供了兼容amqp interop的包装器。

测试

通过运行以下命令创建客户端/服务器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兼容良好

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

许可证

BunnyPHP受MIT许可证许可。请参阅LICENSE文件。