Spring Boot 整合 RabbitMQ 傳送延時訊息

Jason207010發表於2024-09-27
  • 1. Spring Boot 整合 RabbitMQ 傳送延時訊息
    • 1.1. 版本說明
    • 1.2. Spring 配置
    • 1.3. 定義常量
    • 1.4. 配置交換機和佇列
    • 1.5. 測試

1. Spring Boot 整合 RabbitMQ 傳送延時訊息

延時訊息依賴於 rabbitmq-delayed-message-exchange RabbitMQ 外掛實現,Github 地址
啟用該外掛後可以建立 x-delayed-message 型別的交換機,該型別的交換機可以支援延時訊息。
Spring 已原生支援此外掛。
下載相應版本的 .ez 檔案到 RabbitMQ 安裝目錄下的 plugins 資料夾裡,執行以下命令啟用外掛:

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

1.1. 版本說明

構件 版本
spring-boot 2.7.18
spring-boot-starter-amqp 2.7.18

1.2. Spring 配置

spring:
  application:
    name: spring-rabbit-delay-exchange-demo
  rabbitmq:
    addresses: 127.0.0.1:5672
    username: admin
    password: admin
    virtual-host: /

1.3. 定義常量

public static final String QUEUE = "spring-rabbit-delay-exchange-demo-queue";
public static final String EXCHANGE = "spring-rabbit-delay-exchange-demo-exchange";
public static final String DELAYED_ROUTING_KEY = "delayed-routing-key";

1.4. 配置交換機和佇列

@Configuration
@Slf4j
public class RabbitDelayExchangeConfiguration {

    @Bean
    public Queue queue() {
        return QueueBuilder.durable(QUEUE).build();
    }

    @Bean
    public Exchange exchange() {
        return ExchangeBuilder.directExchange(EXCHANGE)
                .delayed() // 設定為延時交換機
                .durable(true)
                .build();
    }

    @Bean
    public Binding binding() {
        return BindingBuilder.bind(queue())
                .to(exchange())
                .with(DELAYED_ROUTING_KEY)
                .noargs();
    }
}

1.5. 測試

@Component
@Slf4j
public class SpringRabbitDelayExchangeDemo implements ApplicationRunner {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        String payload = "this is a delayed message";
        MessageProperties messageProperties = new MessageProperties();
        //延時 3 秒
        messageProperties.setDelay(3000);
        rabbitTemplate.convertAndSend(
                EXCHANGE,
                DELAYED_ROUTING_KEY,
                MessageBuilder.withBody(payload.getBytes(UTF_8))
                        .andProperties(messageProperties)
                        .build()
        );
        log.info("at {} sent a delayed message, exchange: {}, payload: {}", LocalDateTime.now(), EXCHANGE, payload);
    }

    @RabbitListener(queues = {QUEUE})
    public void listen(Message<String> message) {
        log.info(
                "at {} received a message, queue: {}, exchange: {}, payload: {}",
                LocalDateTime.now(),
                message.getHeaders().get(CONSUMER_QUEUE),
                message.getHeaders().get(RECEIVED_EXCHANGE),
                message.getPayload()
        );
    }
}

啟動程式,控制檯將輸出:

at 2024-09-27T14:28:07.183930 sent a delayed message, exchange: spring-rabbit-delay-exchange-demo-exchange, payload: this is a delayed message
at 2024-09-27T14:28:10.261180 received a message, queue: spring-rabbit-delay-exchange-demo-queue, exchange: spring-rabbit-delay-exchange-demo-exchange, payload: this is a delayed message

可以看出在發出訊息 3 秒後接收到了延時訊息。

相關文章