Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Implementing Delayed Message Delivery in RabbitMQ with the Delayed Message Plugin

Tech 1

Plugin Installattion

Download the rabbitmq_delayed_message_exchange plugin archive from the official repository. For this guide, version 3.10.0 is used. Transfer the .ez file to the RabbitMQ server and place it inside the plugins directory of your RabbitMQ installation:

scp rabbitmq_delayed_message_exchange-3.10.0.ez root@10.211.55.4:/usr/local/software/mv rabbitmq_delayed_message_exchange-3.10.0.ez /usr/local/software/rabbitmq_server-3.10.0/plugins

Enable the plugin and restart the broker:

rabbitmq-plugins enable rabbitmq_delayed_message_exchangerabbitmq-server start

After the restart, the plugin adds a new exchange type x-delayed-message that supports holding messages for a configured amount of time before routing them to the target queue.

Configuration with Spring AMQP

A dedicated configuration class registers the needed exchange, queue, and binding. The exchange is set up as a CustomExchange with the type x-delayed-message and an extra argument that defines the underlying routing behaviour (x-delayed-type).

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class DelayedExchangeSetup {

    public static final String ORDER_DELAYED_QUEUE = "orders.delayed.queue";
    public static final String ORDER_DELAYED_EXCHANGE = "orders.delayed.exchange";
    public static final String ORDER_DELAYED_ROUTING = "orders.delayed.key";

    @Bean
    public CustomExchange delayedOrderExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange(ORDER_DELAYED_EXCHANGE,
                "x-delayed-message",
                true,
                false,
                args);
    }

    @Bean
    public Queue delayedOrderQueue() {
        return new Queue(ORDER_DELAYED_QUEUE);
    }

    @Bean
    public Binding delayedOrderBinding() {
        return BindingBuilder
                .bind(delayedOrderQueue())
                .to(delayedOrderExchange())
                .with(ORDER_DELAYED_ROUTING)
                .noargs();
    }
}

Sending Delayed Messages

The producer uses RabbitTemplate and sets the delay (in milliseconds) through the MessagePostProcessor interface.

@RestController
public class OrderController {

    private final RabbitTemplate rabbitTemplate;

    public OrderController(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    @GetMapping("/orders/delayed/{payload}/{delay}")
    public void createDelayedOrder(@PathVariable String payload,
                                   @PathVariable int delay) {
        rabbitTemplate.convertAndSend(
                DelayedExchangeSetup.ORDER_DELAYED_EXCHANGE,
                DelayedExchangeSetup.ORDER_DELAYED_ROUTING,
                payload,
                message -> {
                    message.getMessageProperties().setDelay(delay);
                    return message;
                });
    }
}

Handling Delayed Messages

On the consumer side, a listener is attached to the delayed queue. It receives the message only after the specified delay has elapsed.

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class DelayedOrderProcessor {

    @RabbitListener(queues = DelayedExchangeSetup.ORDER_DELAYED_QUEUE)
    public void process(Message msg) {
        String order = new String(msg.getBody());
        System.out.println("Processing delayed order: " + order);
    }
}

The delayed message plugin ensures that messages are routed strictly according to their individual delay settings, avoidnig the ordering pitfalls sometimes observed with dead‑letter‑based aprpoaches.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.