20.rabbitmq插件实现延迟队列

问题

前面谈到基于死信的延迟队列,存在的问题:如果第一个消息延时时间很长,而第二个消息延时时间很短,第二个消息并不会优先得到执行。

下载插件

地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases

rabbitmq_delayed_message_exchange-3.8.0.ez

**说明:**rabbitmq安装后,会生成这个目录

/usr/lib/rabbitmq/lib/rabbitmq_server-3.8.8/plugins/

拷贝插件到上面这个目录

安装插件

需要重启rabbitmq

监测插件是否安装成功

可以看出不再使用延迟队列,而是使用延迟交换机。

代码

配置代码

java 复制代码
package com.xkj.org.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.CustomExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

@Configuration
public class DelayExchangeConfig {

    //队列
    public static final String DELAYED_QUEUE_NAME = "delayed.queue";
    //交换机
    public static final String DELAYED_EXCHANGE_NAME = "delayed.exchange";
    //RoutingKey
    public static final String DELYAED_ROUTING_KEY = "delayed.routingkey";


    @Bean
    public CustomExchange delayedExchange() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-delayed-type", "direct");
        //第一个参数交换机的名称
        //第二个参数交换机的类型
        //第三个参数是否持久化
        //第四个参数是否删除
        //第五个参数其他参数
        return new CustomExchange(DELAYED_EXCHANGE_NAME, "x-delayed-message", true, false,
                arguments);
    }

    @Bean
    public Queue delayedQueue() {
        return new Queue(DELAYED_QUEUE_NAME);
    }

    @Bean
    public Binding delayedQueueBindingDelayedExchange(@Qualifier("delayedExchange")CustomExchange delayedExchange,
                                                      @Qualifier("delayedQueue")Queue delayedQueue) {
        return BindingBuilder.bind(delayedQueue).to(delayedExchange).with(DELYAED_ROUTING_KEY).noargs();
    }


}

生产者

java 复制代码
@ApiOperation("基于插件的延迟消息")
    @GetMapping("/sendDelayedMsg/{msg}/{delayedTime}")
    public void sendDelayedMsg(@ApiParam(value = "消息内容", required = true)@PathVariable("msg") String message,
                               @ApiParam(value = "延迟时间", required = true)@PathVariable("delayedTime")Integer delayedTime) {
        log.info("当前时间{},发送一条消息给延迟交换机:{},delayedTime={}", new Date().toString(), message, delayedTime);
        rabbitTemplate.convertAndSend("delayed.exchange", "delayed.routingkey", message, msg -> {
            msg.getMessageProperties().setDelay(delayedTime);
            return msg;
        });
    }

消费者

java 复制代码
package com.xkj.org.listener;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Date;


/**
 * 基于插件的延迟消息队列监听
 */
@Slf4j
@Component
public class DelayedQueueConsumer {

    @RabbitListener(queues = "delayed.queue")
    public void receiver(Message message, Channel channel) throws UnsupportedEncodingException {
        String msg = new String(message.getBody(), "UTF-8");
        log.info("当前时间:{},收到延迟队列的消息:{}", new Date().toString(), msg);
    }

}

总结

延迟队列可以保证消息可靠发送,消息可靠投递,死信队列保证消息至少被消费一次,已经未被处理的消息不会被丢弃。

相关推荐
新手小袁_J9 分钟前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
呆呆小雅10 分钟前
C#关键字volatile
java·redis·c#
Monly2111 分钟前
Java(若依):修改Tomcat的版本
java·开发语言·tomcat
Ttang2313 分钟前
Tomcat原理(6)——tomcat完整实现
java·tomcat
goTsHgo14 分钟前
在 Spring Boot 的 MVC 框架中 路径匹配的实现 详解
spring boot·后端·mvc
钱多多_qdd24 分钟前
spring cache源码解析(四)——从@EnableCaching开始来阅读源码
java·spring boot·spring
waicsdn_haha26 分钟前
Java/JDK下载、安装及环境配置超详细教程【Windows10、macOS和Linux图文详解】
java·运维·服务器·开发语言·windows·后端·jdk
飞的肖34 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
Q_192849990636 分钟前
基于Spring Boot的摄影器材租赁回收系统
java·spring boot·后端
Code_流苏38 分钟前
VSCode搭建Java开发环境 2024保姆级安装教程(Java环境搭建+VSCode安装+运行测试+背景图设置)
java·ide·vscode·搭建·java开发环境