BunnyPHP

性能卓越的纯 PHP AMQP(RabbitMQ)同步/异步(ReactPHP)库。「Performant pure-PHP AMQP (RabbitMQ) sync/async (ReactPHP) library」

Github星跟蹤圖

BunnyPHP

Build Status
Downloads this Month
Latest stable

Performant pure-PHP AMQP (RabbitMQ) sync/async (ReactPHP) library

Requirements

BunnyPHP requires PHP 7.0 and newer.

Installation

Add as Composer dependency:

$ composer require bunny/bunny:@dev

Comparison

You might ask if there isn't a library/extension to connect to AMQP broker (e.g. RabbitMQ) already. Yes, there are
multiple options:

Why should you want to choose BunnyPHP instead?

  • You want nice idiomatic PHP API to work with (I'm looking at you, php-amqplib). BunnyPHP interface follows PHP's common
    coding standards and naming conventions. See tutorial.

  • You can't (don't want to) install PECL extension that has latest stable version in 2014. BunnyPHP isn't as such marked
    as stable yet. But it is already being used in production.

  • You have both classic CLI/FPM and ReactPHP applications and need to connect to RabbitMQ.
    BunnyPHP comes with both synchronous and asynchronous clients with same PHP-idiomatic interface. Async client uses
    react/promise.

Apart from that BunnyPHP is more performant than main competing library, php-amqplib. See benchmark/ directory
and php-amqplib's benchmark/.

Benchmarks were run as:

$ php benchmark/producer.php N & php benchmark/consumer.php
```, Library, N (# messages), Produce sec, Produce msg/sec, Consume sec, Consume msg/sec, -------------, ---------------:, ------------:, ----------------:, ------------:, ----------------:, php-amqplib, 100, 0.0131, 7633, 0.0446, 2242, bunnyphp, 100, 0.0128, 7812, 0.0488, 2049, bunnyphp +/-, +2.3%, -8.6%, php-amqplib, 1000, 0.1218, 8210, 0.4801, 2082, bunnyphp, 1000, 0.1042, 9596, 0.2919, 3425, bunnyphp +/-, +17%, +64%, php-amqplib, 10000, 1.1075, 9029, 5.1824, 1929, bunnyphp, 10000, 0.9078, 11015, 2.9058, 3441, bunnyphp +/-, +22%, +78%, php-amqplib, 100000, 20.7005, 4830, 69.0360, 1448, bunnyphp, 100000, 9.7891, 10215, 35.7305, 2789, bunnyphp +/-, +111%, +92%, ## Tutorial

### Connecting

When instantiating the BunnyPHP `Client` accepts an array with connection options:

```php
$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();

Connecting with SSL/TLS

Options for SSL-connections should be specified as array 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();

For options description - please see SSL context options.

Note: invalid SSL configuration will cause connection failure.

See also common configuration variants.

Publish a message

Now that we have a connection with the server we need to create a channel and declare a queue to communicate over before we can publish a message, or subscribe to a queue for that matter.

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

With a communication channel set up, we can now publish a message to the queue:

$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
);

Subscribing to a queue

Subscribing to a queue can be done in two ways. The first way will run indefinitely:

$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'
);

The other way lets you run the client for a specific amount of time consuming the queue before it stops:

$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

Pop a single message from a queue

$message = $channel->get('queue_name');

// Handle message

$channel->ack($message); // Acknowledge message

Prefetch count

A way to control how many messages are prefetched by BunnyPHP when consuming a queue is by using the channel's QOS method. In the example below only 5 messages will be prefetched. Combined with acknowledging messages this turns into an effective flow control for your applications, especially asynchronous applications. No new messages will be fetched unless one has been acknowledged.

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

Asynchronous usage

Bunny supports both synchronous and asynchronous usage utilizing ReactPHP. The following example shows setting up a client and consuming a queue indefinitely.

(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 interop

There is amqp interop compatible wrapper(s) for the bunny library.

Contributing

  • Large part of the PHP code (almost everything in Bunny\Protocol namespace) is generated from spec in file
    spec/amqp-rabbitmq-0.9.1.json. Look for DO NOT EDIT! in doc comments.

    To change generated files change spec/generate.php and run:

    $ php ./spec/generate.php
    

Broker compatibility

Works well with RabbitMQ

Does not work with ActiveMQ because it requires AMQP 1.0 which is a completely different protocol (Bunny is implementing AMQP 0.9.1)

License

BunnyPHP is licensed under MIT license. See LICENSE file.

主要指標

概覽
名稱與所有者jakubkulhan/bunny
主編程語言PHP
編程語言PHP (語言數: 4)
平台
許可證MIT License
所有者活动
創建於2015-03-15 18:20:50
推送於2025-06-02 21:50:33
最后一次提交2025-05-22 11:49:34
發布數24
最新版本名稱v0.5.6 (發布於 2025-05-23 07:33:36)
第一版名稱v0.1.0 (發布於 2015-03-27 11:32:12)
用户参与
星數723
關注者數35
派生數107
提交數231
已啟用問題?
問題數79
打開的問題數29
拉請求數68
打開的拉請求數12
關閉的拉請求數19
项目设置
已啟用Wiki?
已存檔?
是復刻?
已鎖定?
是鏡像?
是私有?