0
votes

I'm using different "Per Message TTL" in RabbitMQ queue, and I expect that messages with different TTL should be processed by consumer in due time.

To provide this behaviour, I use RabbitMQ queue with huge "x-message-ttl", I add messages to this queue with own value of "Per Message TTL"(see code below). For example add to queue messages with TTL 30, 20 and 10 seconds.

The problem in behaviour, how RabbitMQ process the messages with different "Per MessageTTL" in queue, the messages with largest TTL stop the messages with less TTL. So consumer process all mesages together, when largest TTL expire.

Publish message code:

$channel = new AMQPChannel($this->connection);    
$exchange = new AMQPExchange($channel);
$exchange->setName($exchangeName);
$exchange->setType(AMQP_EX_TYPE_DIRECT);        
$ttl = $ttl*1000;    
$params = array('expiration'=>$ttl);    
$message = $exchange->publish($msg, $this->queueNotDelayedName, null, $params);
3

3 Answers

0
votes

I'm going to be up-front that I don't fully understand your question, because the wording is confusing to me.

Are you referring to this (from the documentation)?

When setting per-message TTL however, expired messages can queue up behind non-expired ones until the latter are consumed or expired. Hence resources used by such expired messages will not be freed, and they will be counted in queue statistics (e.g. the number of messages in the queue).

I have not had issues using the per-message TTL feature. The messages expire before they get to the consumer. What the documentation says is that they are not expired in random order out of the queue, but that they are only expired when the message is to be "read" from the queue. Is this the cause of your issue?

0
votes

As correctly noted rmayer06, described functionality works by design.

From http://www.rabbitmq.com/ttl.html#per-message-ttl :

When setting per-message TTL however, expired messages can queue up
behind non-expired ones until the latter are consumed or expired.

I solved my problem programmatically. I used the solution which well described here:

http://yuserinterface.com/dev/2013/01/08/how-to-schedule-delay-messages-with-rabbitmq-using-a-dead-letter-exchange/

0
votes

Unfortunately (imho) theMayer is correct. The message will only expire when it hits the head of the queue. We had a similar issue at our company. In the end we had to implement separate queues as we only had 2 different timeouts so 2 queues. There is a plugin that we are in the middle of investigating that may allow for the operation you seek https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/