Since version 6.0 LTS, Laravel has some available drivers for queue connection, such as
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
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.
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.
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.
In your laravel app's
config/queue.php file, add the new configuration item for
rabbitmq inside the
... '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=
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:
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