loading...

RabbitMQ Queue Driver for Laravel

dendihandian profile image Dendi Handian Updated on ・4 min read

Since version 6.0 LTS, Laravel has some available drivers for queue connection, such as database, Redis, Beanstalkd and AWS SQS. Those external services are great, but there will be a situation when you have to pick the right service for your app in a certain environment. For example, if your app is using AWS as the server then AWS SQS might be the best choice. Maybe there will be a situation when you have to pick another service that not supported (yet) by Laravel and it's the best for your environment and requirement, maybe it's RabbitMQ.

Laravel doesn't support RabbitMQ, but there is a package that enables it to be supported. Thanks to vyuldashev, laravel-queue-rabbitmq is an awesome package to make it happens. I'll show you.


Prerequisites

Of course, you have to set RabbitMQ ready on your machine. If you have no idea how to do it, then you can see my post about setting it up in Laradock here. And for the demo, I will use the simple mail sending example using artisan command that I have practiced here.


Installing laravel-queue-rabbitmq package

By using composer and go to your project directory using CLI, execute this command:

composer require vladimir-yuldashev/laravel-queue-rabbitmq

Wait until the installation is done.

Installing AMQP support package

I will give explanation about AMQP later (maybe), but in order to be work between PHP and rabbitmq, you must install the any available AMQP support package. I have tried AmqpBunny package and it works. So to install the package, execute this command:

composer require enqueue/amqp-bunny:^0.8

Wait until the installation is done.

Configure the queue connection

In your laravel app's config/queue.php file, add the new configuration item for rabbitmq inside the connections array:

config/queue.php:

...

'connections' => [

        ...

        'rabbitmq' => [

            'driver' => 'rabbitmq',

            /*
         * Set to "horizon" if you wish to use Laravel Horizon.
         */
            'worker' => env('RABBITMQ_WORKER', 'default'),

            'dsn' => env('RABBITMQ_DSN', null),

            /*
         * Could be one a class that implements \Interop\Amqp\AmqpConnectionFactory for example:
         *  - \EnqueueAmqpExt\AmqpConnectionFactory if you install enqueue/amqp-ext
         *  - \EnqueueAmqpLib\AmqpConnectionFactory if you install enqueue/amqp-lib
         *  - \EnqueueAmqpBunny\AmqpConnectionFactory if you install enqueue/amqp-bunny
         */

            'factory_class' => \Enqueue\AmqpBunny\AmqpConnectionFactory::class,

            'host' => env('RABBITMQ_HOST', '127.0.0.1'),
            'port' => env('RABBITMQ_PORT', 5672),

            'vhost' => env('RABBITMQ_VHOST', '/'),
            'login' => env('RABBITMQ_LOGIN', 'guest'),
            'password' => env('RABBITMQ_PASSWORD', 'guest'),

            'queue' => env('RABBITMQ_QUEUE', 'default'),

            'options' => [

                'exchange' => [

                    'name' => env('RABBITMQ_EXCHANGE_NAME'),

                    /*
                 * Determine if exchange should be created if it does not exist.
                 */

                    'declare' => env('RABBITMQ_EXCHANGE_DECLARE', true),

                    /*
                 * Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
                 */

                    'type' => env('RABBITMQ_EXCHANGE_TYPE', \Interop\Amqp\AmqpTopic::TYPE_DIRECT),
                    'passive' => env('RABBITMQ_EXCHANGE_PASSIVE', false),
                    'durable' => env('RABBITMQ_EXCHANGE_DURABLE', true),
                    'auto_delete' => env('RABBITMQ_EXCHANGE_AUTODELETE', false),
                    'arguments' => env('RABBITMQ_EXCHANGE_ARGUMENTS'),
                ],

                'queue' => [

                    /*
                 * Determine if queue should be created if it does not exist.
                 */

                    'declare' => env('RABBITMQ_QUEUE_DECLARE', true),

                    /*
                 * Determine if queue should be binded to the exchange created.
                 */

                    'bind' => env('RABBITMQ_QUEUE_DECLARE_BIND', true),

                    /*
                 * Read more about possible values at https://www.rabbitmq.com/tutorials/amqp-concepts.html
                 */

                    'passive' => env('RABBITMQ_QUEUE_PASSIVE', false),
                    'durable' => env('RABBITMQ_QUEUE_DURABLE', true),
                    'exclusive' => env('RABBITMQ_QUEUE_EXCLUSIVE', false),
                    'auto_delete' => env('RABBITMQ_QUEUE_AUTODELETE', false),
                    'arguments' => env('RABBITMQ_QUEUE_ARGUMENTS'),
                ],
            ],

            /*
         * Determine the number of seconds to sleep if there's an error communicating with rabbitmq
         * If set to false, it'll throw an exception rather than doing the sleep for X seconds.
         */

            'sleep_on_error' => env('RABBITMQ_ERROR_SLEEP', 5),

            /*
         * Optional SSL params if an SSL connection is used
         * Using an SSL connection will also require to configure your RabbitMQ to enable SSL. More details can be founds here: https://www.rabbitmq.com/ssl.html
         */

            'ssl_params' => [
                'ssl_on' => env('RABBITMQ_SSL', false),
                'cafile' => env('RABBITMQ_SSL_CAFILE', null),
                'local_cert' => env('RABBITMQ_SSL_LOCALCERT', null),
                'local_key' => env('RABBITMQ_SSL_LOCALKEY', null),
                'verify_peer' => env('RABBITMQ_SSL_VERIFY_PEER', true),
                'passphrase' => env('RABBITMQ_SSL_PASSPHRASE', null),
            ],
        ],
    ],

...

And in your laravel app's .env file, set parameters into like this:

QUEUE_CONNECTION=rabbitmq

RABBITMQ_HOST=rabbitmq
RABBITMQ_PORT=5672
RABBITMQ_VHOST=/
RABBITMQ_LOGIN=guest
RABBITMQ_PASSWORD=guest
RABBITMQ_QUEUE=default

RABBITMQ_EXCHANGE_NAME=default
RABBITMQ_EXCHANGE_DECLARE=
RABBITMQ_EXCHANGE_TYPE=
RABBITMQ_EXCHANGE_PASSIVE=
RABBITMQ_EXCHANGE_DURABLE=
RABBITMQ_EXCHANGE_AUTODELETE=
RABBITMQ_EXCHANGE_ARGUMENTS=default

RABBITMQ_QUEUE_DECLARE=
RABBITMQ_QUEUE_DECLARE_BIND=
RABBITMQ_QUEUE_PASSIVE=
RABBITMQ_QUEUE_DURABLE=
RABBITMQ_QUEUE_EXCLUSIVE=
RABBITMQ_QUEUE_AUTODELETE=
RABBITMQ_QUEUE_ARGUMENTS=default

RABBITMQ_ERROR_SLEEP=5

RABBITMQ_SSL=
RABBITMQ_SSL_CAFILE=
RABBITMQ_SSL_LOCALCERT=
RABBITMQ_SSL_LOCALKEY=
RABBITMQ_SSL_VERIFY_PEER=
RABBITMQ_SSL_PASSPHRASE=

RabbitMQ connection test and demo

You can check the rabbitmq management first to make sure the Queues still empty and maybe stop the php-worker first if you use it to see the stored queue job later before it executed automatically.

We will use an artisan command to send an email as I practiced before while demonstrating mailhog or php-worker. So, enter the project directory using CLI if you haven't and execute the artisan command:

php artisan example:send-mail

If you managed to disable the php-worker before, you should see the queue has 1 job ready to be executed:

2020-04-01-00h30-25

Then start the worker to see if it's working for real.


Have fun experimenting RabbitMQ with Laravel!


versions used:
 - laravel: 6.0 LTS
 - rabbitmq: 3.8.1
 - laravel-queue-rabbitmq: ^10.0
 - enqueue/amqp-bunny: ^0.8

Posted on by:

dendihandian profile

Dendi Handian

@dendihandian

A backend developer by heart, a fullstack developer wannabe. A data scientist dreamer.

Discussion

markdown guide