java-设置手动消费的rabbit延时队列

参考

使用之前的预先工作

使用rabbit支持的  x-delay-message 插件实现延时队列的方式
rabbit版本3.7.10 erlang 23.1.3

依赖包

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    <version>1.5.2.RELEASE</version>
</dependency>

yml配置

rabbitmq:
  username: aaa
  password: bbb
  host: ip
  port: 5672
  listener:
    simple:
# 消费模式手动 acknowledge-mode: manual concurrency: 2
# 最多同时在线 max-concurrency: 2 # 是否开启消费者重试(为false时关闭消费者重试) # retry: # enabled: true # 最大重试重新投递消息次数 # max-attempts: 2 # 重试重新投递消息的间隔时间(单位毫秒) # initial-interval: 600000ms

rabbitMqConfig.java   队列的配置

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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * 队列配置
 *
 * @Author
 * @Date
 **/
@Configuration
public class XDelayConfig {

    /**
     * 立即消费的队列名称
     */
    public static final String IMMEDIATE_QUEUE_XDELAY = "queue.xdelay.immediate";
    /**
     * 延时的exchange交换机
     */
    public static final String DELAYED_EXCHANGE_XDELAY = "exchange.xdelay.delayed";
    public static final String DELAY_ROUTING_KEY_XDELAY = "routingkey.xdelay.delay";

    /**
     * 使用rabbit支持的  x-delay-message 插件实现延时队列的方式
     * rabbit版本3.7.10 erlang 23.1.3
     * 创建一个立即消费队列
     * @return
     */
    @Bean
    public Queue immediateQueue() {
        // 第一个参数是创建的queue的名字,第二个参数是是否支持持久化
        return new Queue(IMMEDIATE_QUEUE_XDELAY, true);
    }

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

    /**
     * 把立即消费的队列和延时消费的exchange绑定在一起
     *
     * @return
     */
    @Bean
    public Binding bindingNotify() {
        return BindingBuilder.bind(immediateQueue()).to(delayExchange()).with(DELAY_ROUTING_KEY_XDELAY).noargs();
    }

}

生产者

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 生产者
 *
 * @Author
 * @Date
 **/
@Component
@Slf4j
public class XDelaySender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 生产者
     * @param msg 发送的消息
     * @param delayTime 延迟的毫秒
     */
    public void sender(String msg, int delayTime) {
        log.info("生产者,msg= " + msg + " .delayTime:" + delayTime);
        this.rabbitTemplate.convertAndSend(XDelayConfig.DELAYED_EXCHANGE_XDELAY, XDelayConfig.DELAY_ROUTING_KEY_XDELAY, msg, message -> {
            message.getMessageProperties().setDelay(delayTime);
            return message;
        });
    }

}  

消费者

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * 消费者
 *
 * @Author
 * @Date
 **/
@Component
@EnableRabbit
@Configuration
@Slf4j
public class XDelayReceiver {

    /**
     * 消费者
     * @param msg
     */
    @RabbitListener(queues = XDelayConfig.IMMEDIATE_QUEUE_XDELAY)
    public void waitReceiver(String msg, Channel channel, @Headers Map<String,Object> headers) throws Exception {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String getkey = (String) JSONObject.parseObject(msg).get("key");
            log.info("收到延时消息时间:" + sdf.format(new Date()) + " Delay sent. 收到延时消息:" + getkey);
            // 处理
            // todo 做想要消费的逻辑

        } catch (Exception e) {
            log.info("消费者,消费失败,消息:" + msg, e);
        }
        long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
        log.info("waitReceiver Tag:" + deliveryTag);
        // 手动确认消费
        channel.basicAck(deliveryTag,false);
    }

}

  

posted @ 2021-01-21 15:34  fatetop  阅读(228)  评论(0编辑  收藏  举报