Springboot与RabbitMQ上手之延迟队列插件(七)

前言

目的主要是学习RabbitMQ的延迟队列插件实现延迟队列,大概会简单介绍学习为主:毕竟还是要来演示Springboot整合RabbitMQ注解的方式来使用。

一.首先插件安装

首先我们需要下载并安装RabbitMQ的延迟插件。
请根据自身rabbitmq版本安装插件

  • RabbitMQ下载插件,插件地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases/tag/v3.8.0
    image.png

二. 安装插件

  • 上传到服务器/home/xxx/文件下,然后进行如下操作
  1. 查看docker 容器的ID
docker ps
image.png
  1. 拷贝到rabbitmq 容器 ID 中
docker cp /home/xxx/rabbitmq_delayed_message_exchange-3.8.0.ez 773067241f96:/plugins
  1. 进入容器
docker exec -it 容器ID /bin/bash
image.png
  1. 启用插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
  1. 查看
rabbitmq-plugins list
image.png

6.重新启动容器

docker restart 容器ID

三、实现延迟队列

自己手动画了 个图,方便理解理解


image.png
3.1 生产者

config

插件安装好后,可以登上web管理台,在添加交换机时可以看到多了一个x-delayed-message类型,而这个类型是rabbitmq_delayed_message_exchange插件提供的,RabbitMQ自己是没有的,可以通过x-delayed-type参数设置fanout /direct / topic / header 类型。

    /** 延迟队列*/
    @Bean
    public Exchange CustomExchange(){
        Map args = new HashMap<>();
        args.put("x-delayed-type", "direct");
// 一定要声明x-delayed-message
        return new CustomExchange("delayed.exchange.test","x-delayed-message",true,false,args);
    }

    // 声明过期的队列并定义队列名称
    @Bean
    public Queue delayQueue(){

        return new Queue("delayed.queue.test"
                ,true,false,false);
    }

    @Bean
    public Binding delayBinding(){
        return new Binding("delayed.queue.test",
                Binding.DestinationType.QUEUE,
                "delayed.exchange.test",
                "key.queue.delayed",null);
    }

servie

    // 延迟队列
    public void delayedMessage() throws JsonProcessingException;

impl

    /**
     * 延迟队列
     */
    @Override
    public void delayedMessage() throws JsonProcessingException {
        /* 使用MessageProperties传递的对象转换成message*/
        MessageProperties messageProperties = new MessageProperties();
        OrderMessageDTO orderMessageDTO = new OrderMessageDTO();
        orderMessageDTO.setProductId(100);
        orderMessageDTO.setPrice(new BigDecimal("20"));
        orderMessageDTO.setOrderId(1);
        String messageToSend = objectMapper.writeValueAsString(orderMessageDTO);
        Message message = new Message(messageToSend.getBytes(),messageProperties);
        // 发送端确认是否确认消费
        CorrelationData correlationData = new CorrelationData();
        // 唯一ID
        correlationData.setId(orderMessageDTO.getOrderId().toString());
        rabbitTemplate.convertAndSend("delayed.exchange.test","key.queue.delayed",messageToSend,
                message1 -> {
                    // 设置过期时间
                    message1.getMessageProperties().setHeader("x-delay",20000);
                    return message1;
                },
                correlationData);
    }

controller

@RestController
@Slf4j
@RequestMapping("/api")
public class SendController {
    @GetMapping("/delayedQueue")
    public void delayedQueue() throws JsonProcessingException {
        directService.delayedMessage();
    }
}

3.2 消费端
service

    // 监听延迟队列,
    public void delayedQueueListenter(Message message, Channel channel) throws IOException;

impl

    @Override
    public void delayedQueueListenter(@Payload Message message, Channel channel) throws IOException {
        log.info("========direct延迟队列,业务场景订单 超时===========");
        DefaultConsumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String message = new String(body, "UTF-8");
                log.info("[x] Received '" + message + "'");
                // 手动 false ack
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        //. 设置 Channel 消费者绑定队列
        channel.basicConsume("delayed.queue.test",false,consumer);
    }

你可能感兴趣的:(Springboot与RabbitMQ上手之延迟队列插件(七))