SpringBoot集成RabbitMQ消息队列搭建实现延时队列

1、软件准备首先安装一个RabbitMQ

本文使用的是linux版本的RabbitMQ,版本是:

rabbitmq-server-3.6.15-1.el6.noarch.rpm

rabbitmq_delayed_message_exchange插件
插件下载地址:

http://www.rabbitmq.com/community-plugins.html

SpringBoot集成RabbitMQ消息队列搭建实现延时队列_第1张图片

由于我安装的是3.6.*系列的版本号,因此对应的rabbitmq_delayed_message_exchange插件也选择3.6.x的,怕版本不对应不兼容踩坑就麻烦了。下载后将解压后的rabbitmq_delayed_message_exchange-20171215-3.6.x.ez 放在RabbitMQ安装目录下的plugins目录下,并使用如下命令启动这个插件:

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

最后在RabbitMQ安装根目录使用这个命令:sbin/rabbitmq-plugins list ,查看是否已经安装rabbitmq_delayed_message_exchange插件

SpringBoot集成RabbitMQ消息队列搭建实现延时队列_第2张图片

 

 

2、集成RabbitMQ

由于我是用的gradle 所以直接为了方便快捷直接引入了,cloud版本可以自己搞成F或者G的都没问题

compile "org.springframework.cloud:spring-cloud-dependencies:Edgware.SR6"

Spring Boot的版本我使用的是1.5.7.RELEASE

接下来在application.yml文件中加入mq配置:

SpringBoot集成RabbitMQ消息队列搭建实现延时队列_第3张图片

 

3、定义ConnectionFactory、RabbitTemplate、Exchange、Queue配置


也很简单,代码如下:

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

    @Bean
    public Queue getSingleToDelayQueue() {
        return new Queue(rabbitMqProperty.getSingleToDelayQueue());
    }

    @Bean
    public Binding getSingleToDelayRoutingkey() {
        return BindingBuilder.bind(getSingleToDelayQueue()).to(getSingleToDelayExchange()).with(rabbitMqProperty.getSingleToDelayRoutingkey()).noargs();
    }
    /**
     * 因为要设置回调类,所以应是prototype类型,如果是singleton类型,则回调类为最后一次设置
     */
    @Bean
//    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setMessageConverter(messageConverter);
        return template;
    }

    @Bean(name = "simpleRabbitListenerContainerFactory")
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMaxConcurrentConsumers(20);
        factory.setConcurrentConsumers(5);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setMessageConverter(messageConverter);
        return factory;
    }

    @Bean
    public MessageConverter messageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean(name = "rabbitAdmin")
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        return new RabbitAdmin(connectionFactory);
    }

4、实现消息发送

public class DelayQueueProducer {
    @Resource
    RabbitMqSendUtil rabbitMqSendUtil;
    @Resource
    RabbitMqProperty rabbitMqProperty;
    public void sendMsg(String msg,int expires) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("消息发送时间:"+sdf.format(new Date()));
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setHeader("x-delay",expires);
                return message;
            }
        };
        rabbitMqSendUtil.send(rabbitMqProperty.getSingleToDelayExchange(), rabbitMqProperty.getSingleToDelayRoutingkey(), msg,messagePostProcessor);
    }

}

 

5、消息消费

@Component
public class DelayQuerueConsumer {
    @RabbitListener(queues = "${spring.rabbitmq.SingleToDelayQueue}")
    @RabbitHandler
    public void receive(String msg, Channel channel, Message message) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("消息接收时间:"+sdf.format(new Date()));
        System.out.println("接收到的消息:"+msg);
        try {
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

6、允许结果

分别调用模拟测试先发送一个10秒、一个2秒的延迟消息。都可以完美消费

SpringBoot集成RabbitMQ消息队列搭建实现延时队列_第4张图片

 

你可能感兴趣的:(JAVA)