Laravel RabbitMQ с нуля и для новичков
Всем привет. Сегодня я расскажу про очереди и их подключения в Laravel 8. Поступила задача перейти на RabbitMQ, для этого был выбран cloudamqp.com.
Цель: сделать монолит в рамках одного микросервиса, т.е. отправка и получение задания будет делать один микросервис, это я называю монолитом.
Для этой задачи мне понадобится пакет https://github.com/vyuldashev/laravel-queue-rabbitmq, есть и другие пакеты:
- https://github.com/php-amqplib/php-amqplib
- https://github.com/jakubkulhan/bunny
На мой взгляд более удачные и понятные, но будем использовать самый первый от Vyuldashev, т.к. о нем я узнал, в начале, а другие пакеты вылезли в процессе работы и они более универсальны.
Установка пакета
composer require vladimir-yuldashev/laravel-queue-rabbitmq
Настройка подключения config/queue.php
'connections' => [ // ... 'rabbitmq' => [ 'driver' => 'rabbitmq', 'queue' => env('RABBITMQ_QUEUE', 'default'), 'connection' => PhpAmqpLib\Connection\AMQPLazyConnection::class, 'hosts' => [ [ 'host' => env('RABBITMQ_HOST', '127.0.0.1'), 'port' => env('RABBITMQ_PORT', 5672), 'user' => env('RABBITMQ_USER', 'guest'), 'password' => env('RABBITMQ_PASSWORD', 'guest'), 'vhost' => env('RABBITMQ_VHOST', '/'), ], ], 'options' => [ 'ssl_options' => [ '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), ], 'queue' => [ 'job' => VladimirYuldashev\LaravelQueueRabbitMQ\Queue\Jobs\RabbitMQJob::class, ], ], // Horizon я не использую, по этому я закомментировал этот блок /* * Set to "horizon" if you wish to use Laravel Horizon. */ #'worker' => env('RABBITMQ_WORKER', 'default'), ],
Все стандартно из документации.
Обновляем настройки .env файла
QUEUE_CONNECTION=rabbitmq RABBITMQ_DSN=amqp:// RABBITMQ_HOST=woodpecker.rmq.cloudamqp.com RABBITMQ_PORT=5672 RABBITMQ_VHOST=feniksdv RABBITMQ_USER=feniksdv RABBITMQ_PASSWORD=Bctt-m_Wfgr12342567н67567thjgj
Все настройки закончены. Теперь переходим к коду.
Мне нужно сделать, чтобы что-то работало через очередь RabbitMQ, пусть это будет отправка простого текста для наглядности и простоты кода.
Что понадобится:
- Route
- SendController
- SendJob
Код я буду писать в контроллере, но так делать в реальных проекта не следует, переносите весь код в сервисы, а я делаю это для сокращения кода.
Route
Route::get('send/text', [SendController::class, 'sendText']);
SendController
class SendController extends Controller { public function sendText() { SendTextJob::dispatch()->onQueue('text'); } }
В контроллере я жестко указал имя очереди text, эта очередь автоматом создастся при первом обращении в cloudamqp.com.
SendJob
class SendTextJob implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; /** * Create a new job instance. * * @return void */ public function __construct() { // } /** * Выведет текст в консоли */ public function handle() { echo "text"; } }
Ну тут все просто, выводит в консоль text.
Пояснения
И так как же работает RabbitMQ — в контроллере я создал dispatch он запускает textJob, и все данные которые передаются в job сериализуются и отправляются в очередь RabbitMQ. Т.е. по факту, мы можем внутри конструкта определить какие-либо данные и они отправляются в очередь. Затем когда запускается очередь Lаravel (php artisan queue:work), то данные забираются из RabbitMQ и десериализуются, и происходит вывод в консоль text.
AmazonMQ
А теперь давайте рассмотрим это зверя. Вроде все просто, но есть нюансы. Регистрируемся в aws.amazon.com, там все просто, я думаю разберетесь.
После чего жмем All Services и ищем AmazonMQ.
Затем жмем create brokers.
Дальше нужно его сконфигурировать, делаем как я. Смотрите скриншоты.
Дальше ждем примерно минут 15 пока запрос обработается.
В процессе создания вы указали логин и пароль, с помощью которого вы будите подключаться к web-морде rabbitMQ, а также использовать их в своем коде для аунтетификации своего приложения.
В самом начале я писал про библиотеки, которые использую, так вот чтобы отправить, что-то в амазон я использовал https://github.com/php-amqplib/php-amqplib с другими либами не завелось, там нужно указывать как-то ssl я не разобрался, если кто понял, то отпишитесь в комментриях.
В официально https://www.rabbitmq.com/tutorials/tutorial-three-php.html документации везде используется выше указанная документация, по этому я на ней и остановился.
Web-morda
Переходите в созданный контейнер test, мотайте в самый низ и смотрите свои ссылки для подключения.
Настройка
Теперь необходимо настроить RabbitMQ, переходим во вкладку exchanges и создаем новый.
Затем переходим в Queues и создаем новую очередь.
Дальше у вас появится новая очередь confirm нажимаем на неё, и связываем exchanges с Queues. Заходим в очередь confirm, просто нажмите на неё и выберите пункт Bindings.
На этом настройка закончена, переходим к написанию кода. Чтобы не растягивать, я создам подключения прямо в контроллере, но так делать нельзя, пишите логику в сервисах.
$host = 'b-fe17fe41-0ed3-4262-a987-33d2a19a0749.mq.us-east-2.amazonaws.com'; $vhost = '/'; // The default vhost is / $user = 'test'; // The default user is guest $pass = '12345678'; // The default password is guest $port = 5671; $data = "info: Hello World!"; $exchange = 'email'; $connection = new AMQPSSLConnection($host, $port, $user, $pass, $vhost, ['verify_peer_name' => false], [], 'ssl'); $channel = $connection->channel(); $msg = new AMQPMessage($data); $channel->batch_basic_publish($msg, $exchange); $channel->publish_batch(); $channel->close(); $connection->close();
Ну собственно все, за более подробными пояснениями, можно почитать документацию или спросить в комментариях.
Предыдущая