0

I have a php daemon, which uses php-amqplib, that consumes messages from RabbitMQ server. Here is a gist of it (though it's a bit more complex than that):

$callback = function (AMQPMessage $msg) {
    echo "Handling event: some event name here";
    try {
      //some custom logic here
    } catch (\Throwable $e) {
      //write error in a log here
    }
    
    $msg->ack();
};

$channel = $this->connection->channel();
$channel->basic_qos(null, 1, null);

$channel->basic_consume($queue, '', false, false, false, false, $callback);

$this->wait($channel);

while ($channel->is_open()) {
   $channel->wait();
}

$channel->close();
$this->connection->close();

When I run it in the background, it handles the events, writes output and errors to various logs and I can see in RabbitMQ control panel that the queue has consumers. Then after quite some time it just stops doing that: there are no messages appearing in both error and output logs, the RabbitMQ control panel shows that the queue has 0 consumers, but the process is still running somehow.

1 Answer 1

3

If the process continue running, but doesn't receive events from rabbitMQ, this may be caused by lost connection between consumer and rabbit server. Maybe the connection was closed by server. By default, if rabbitMQ server does not receive ack signal from consumer in some meaningful timeout (depends on configuration), it thinks that consumer is dead, closes the connection and re-queues the message. I.e. if message processing takes a long time and your consumer does not send ack within this timeout, connection is lost. To fix this you could send so-called "heartbeats" to server, to say like "hey, I'm alive, just give me more time to process a message". RabbitMq client should do it automatically, but there is some bug in php implementation. See this article for details: https://blog.mollie.com/keeping-rabbitmq-connections-alive-in-php-b11cb657d5fb

Sign up to request clarification or add additional context in comments.

3 Comments

What if my settings for connection have a heartbeat set to 0? I use AMQPStreamConnection and pass 0 as the heartbeat argument. I tried to manually recreate this bug, by faking a long event processing time, by adding sleep(999999) to my callback, but rabbitmq still didn't drop the consumer even after 20 or so minutes of callback running
I don't know a lot about RabbitMQ configuration, just know that such an issue exists. Maybe this is not your case, or the default timeout is more than 20 min.
It looks like simply setting the heartbeat to non zero value solved the problem, thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.