In my Spring Cloud Stream article, I explained how to use RabbitMQ’s delayed messages to implement scheduled tasks. Recently, developers have encountered a situation where delayed messages have no effect and are consumed directly. Therefore, I continue to study the cause of the problem in depth, and record it here for the reference of children who encounter similar problems.

Problem orientation

Since not all messages exhibit factors that do not delay the message effect, it is possible to guess from the problematic message characteristics that the delay time is too long to delay the message. To verify this, take the example from the previous article and test whether the delay time is directly related to the problem.

A slight modification to the previous delay message sample interface (available in Git repository at the end of this article) adds a request parameter delay to control the delay time:

@GetMapping("/sendMessage")
public String messageWithMQ(@RequestParam String message, @RequestParam Long delay) {
    log.info("Send: " + message);
    testTopic.output().send(MessageBuilder.withPayload(message).setHeader("x-delay", delay).build());
    return "ok";
}
Copy the code

Then I tried to make two requests:

Request 1: Delay 5000 ms. There was indeed a 5 second delay after the message was sent to MQ before it was consumed without any problems.

curl localhost:8080/sendMessage? message=hello&delay=5000Copy the code

Request 2: Delay 1 year (31536000000 ms). Messages sent to MQ are consumed by consumers immediately, with no delay at all.

curl localhost:8080/sendMessage? message=hello&delay=31536000000Copy the code

The problem summary

After identifying the cause of the problem, some clear limits (latency limits) need to be put on the functionality to avoid similar problems. Digging deeper, the failure here is directly related to the expiration time (TTL) of the message. In RabbitMQ, the expiration time of a message must be a non-negative 32-bit integer, in milliseconds, 0 <= n <= 2^32-1. Where 2^32-1 = 4294967295.

Here we can try the following two requests and set the delay time to 4294967295 and 4294967296 respectively:

curl localhost:8080/sendMessage? message=hello&delay=4294967295 curl localhost:8080/sendMessage? message=hello&delay=4294967296Copy the code

It can be found that when the delay time is 4294967295 ms, the delay message works normally. When the delay time is 4294967296 ms, the message is consumed directly with no delay effect.

So, when using RabbitMQ’s delay messaging feature, we must note that the delay limit is 4294967296 milliseconds. If your business needs exceed this threshold, you must avoid this trap and find other ways to implement tasks that require delayed or timed execution.

Code sample

Readers of the sample article can check out the stream-delayed-message project in the following repository:

  • Making: github.com/dyc87112/Sp…
  • Gitee: gitee.com/didispace/S…

If you are interested in these, welcome to star, follow, favorites, forward to give support!

Welcome to pay attention to my official account: Program ape DD, for exclusive learning resources and daily dry goods push. If you are interested in my feature content, you can also follow my blog: didispace.com