I'm implementing the Notifications system using RabbitMQ and would like to hear the best practices for the following issues.
RabbitMQ server is installed on a localhost.
My code for Producer:
// ... Initialize connection
$this->channel->exchange_declare('my_exchange', 'direct', false, false, false);
// Detect routing key
$parameters = $notification->getParameters();
$routing_key = !empty($parameters['consumer']) ? $parameters['consumer'] : 'admin.0';
$message = new AMQPMessage($notification->getMessage(), ['delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT]);
$this->channel->basic_publish($message, 'my_exchange', $routing_key);
// ... Close connection
My code for Consumer:
// ... Initialize connection
$channel->exchange_declare('my_exchange', 'direct', false, false, false);
list($queue_name, ,) = $channel->queue_declare("", false, false, true, false);
// Bind admin routing key
$channel->queue_bind($queue_name, 'my_exchange', "admin.0");
// Bind seller routing keys
foreach ($sellers_ids_from_db as $seller_id) {
$channel->queue_bind($queue_name, 'my_exchange', "seller.{$seller_id}");
}
// Bind customer routing keys
foreach ($customers_ids_from_db as $customer_id) {
$channel->queue_bind($queue_name, 'my_exchange', "customer.{$customer_id}");
}
echo " [*] Waiting for logs. To exit press CTRL+C
";
$channel->basic_consume($queue_name, '', false, false, false, false, function ($msg) {
echo ' [x] ', $msg->delivery_info['routing_key'], ':', $msg->body, "
";
});
while (count($channel->callbacks)) {
$channel->wait();
}
// ... Close connection
According to the docs, a Consumer should be stored in a seperate php script and should be called from the terminal (e.g. php Consumer.php
), but what if we don't have access to it (common issue on a shared hosting)? First solution that comes in mind is to execute php from the code (using exec('php Consumer.php')
), but is it a good practice? Still, execs could also be forbidden, what is the solution then?
Or maybe there is a way to somehow have a Consumer in a class method and call it?
There are three groups of users that should receive notifications: admins, sellers and customers. Currently, I have a queue for each user in each group (e.g. queues admin.1
, admin.2
, seller.1
, seller.2
etc.). Using this approach, I have to start a Consumer only once, but the problem is that I have to restart it each time a new user is added to any group. Is there a better implementation for this?
Thanks in advance!