André Figueira

Systems engineer - I write apps, I make websites, opinions are my own...

Fix a consumer disconnecting from RabbitMQ with no errors

I recently ran across an issue with some consumers I have running against RabbitMQ, they were failing after processing messages for a limited amount of time, After an insane amount of debugging, I found the problem!

Basically, RabbitMQ was failing to perform a heartbeat, with PHP by default there is no heartbeat sent to RabbitMQ, when using the amqp-lib

    public function __construct(
        $host,
        $port,
        $user,
        $password,
        $vhost = '/',
        $insist = false,
        $login_method = 'AMQPLAIN',
        $login_response = null,
        $locale = 'en_US',
        $connection_timeout = 3.0,
        $read_write_timeout = 3.0,
        $context = null,
        $keepalive = false,
        $heartbeat = 0
    ) {
        $io = new StreamIO(
            $host,
            $port,
            $connection_timeout,
            $read_write_timeout,
            $context,
            $keepalive,
            $heartbeat
        );
        parent::__construct(
            $user,
            $password,
            $vhost,
            $insist,
            $login_method,
            $login_response,
            $locale,
            $io,
            $heartbeat
        );
        // save the params for the use of __clone, this will overwrite the parent
        $this->construct_params = func_get_args();
    }

I was passing in this parameter from dotenv config file, and had forgotten to cast it as an integer, unfortunately there is no validation on the AMQPConnection classes in the amqp-lib so it was a tad difficult to realise the error as I mentioned there were no errors, the consumer kept running, it simply disconnected.

What I traced to be in fact happening was, RabbitMQ would take the string heartbeat value, and attempt to act on it, and it was failing to perform the heartbeat, which would then in turn end up in an internal silent error on RabbitMQ's side.

Anyway, the lesson is, double check all the values you're passing to third parties are correct!

<3