记录springboot连接rabbitmq实现延时队列, 遇到的坑

rabbitmq配置类

@Configuration
public class RabbitMQConfig {
	public final static String DEAD_LETTER_EXCHANGE = "x-dead-letter-exchange";
	public final static String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";


	@Bean
	public ConnectionFactory connectionFactory() {
		CachingConnectionFactory connectionFactory = new CachingConnectionFactory("127.0.0.1", 5672);
		connectionFactory.setUsername("chy");
		connectionFactory.setPassword("123");
		return connectionFactory;
	}

	@Bean
	public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
		return new RabbitTemplate(connectionFactory);
	}

	/**
	 * 死信队列跟交换机类型没有关系 不一定为directExchange  不影响该类型交换机的特性.
	 *
	 * @return the exchange
	 */
	@Primary
	@Bean("deadLetterExchange")
	public Exchange deadLetterExchange() {
		return ExchangeBuilder.directExchange("DL_EXCHANGE").durable(true).build();
	}

	/**
	 * 声明一个死信队列.
	 * x-dead-letter-exchange   对应  死信交换机
	 * x-dead-letter-routing-key  对应 死信队列
	 *
	 * @return the queue
	 */
	@Bean("deadLetterQueue")
	public Queue deadLetterQueue() {
		Map<String, Object> args = new HashMap<>(2);
//       x-dead-letter-exchange    声明  死信交换机
		args.put(DEAD_LETTER_EXCHANGE, "REDIRECT_EXCHANGE");
//       x-dead-letter-routing-key    声明 死信路由键
		args.put(DEAD_LETTER_ROUTING_KEY, "KEY_R");
		return QueueBuilder.durable("DL_QUEUE").withArguments(args).build();
	}

	/**
	 * 定义死信队列转发队列.
	 *
	 * @return the queue
	 */
	@Primary
	@Bean("redirectQueue")
	public Queue redirectQueue() {
		return QueueBuilder.durable("REDIRECT_QUEUE").build();
	}

	/**
	 * 定义死信队列转发交换机.
	 *
	 * @return the queue
	 */
	@Bean("redirectExchange")
	public Exchange redirectExchange() {
		return ExchangeBuilder.directExchange("REDIRECT_EXCHANGE").durable(true).build();
	}

	/**
	 * 死信交换机通过DL_KEY 绑定键绑定到死信队列上.
	 *
	 * @return the binding
	 */
	@Bean
	public Binding deadLetterBinding() {
		return new Binding("DL_QUEUE", Binding.DestinationType.QUEUE, "DL_EXCHANGE", "DL_KEY", null);

	}

	/**
	 * 转发交换机通过 KEY_R 绑定键绑定到转发队列上
	 *
	 * @return the binding
	 */
	@Bean
	public Binding redirectBinding() {
		return new Binding("REDIRECT_QUEUE", Binding.DestinationType.QUEUE, "REDIRECT_EXCHANGE", "KEY_R", null);
	}



}

发送延时消息

@Controller
public class TestController {

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@RequestMapping(value = "/test", method = RequestMethod.GET)
	public String test(String content){
		byte[] body = "hello,zhihao.miao".getBytes();

		MessageProperties messageProperties = new MessageProperties();
		messageProperties.setContentType("json");
		//设置消息的过期时间
		messageProperties.setExpiration("3000");

		Message message = new Message(body,messageProperties);

		rabbitTemplate.send("DL_EXCHANGE","DL_KEY",message);
		return ResponseBuilder.SUCCESS();
	}
}

消费死信队列中的消息

@Component
public class Consumer {
	private static final Logger logger = LoggerFactory.getLogger(Consumer.class);

	/**
	 * 监听替补队列 来验证死信.
	 *
	 * @param message the message
	 * @param channel the channel
	 * @throws IOException the io exception  这里异常需要处理
	 */
	@RabbitListener(queues = {"REDIRECT_QUEUE"})
	public void redirect(Message message, Channel channel) throws IOException {
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
		logger.info("dead message  3s 后 消费消息 {}",new String (message.getBody()));
	}
}

自认为, 配置没有错可是发送的延时消息就是没有过期. 头很大. 这个问题卡了我1天多的时间. 后面无意间发现,

修改队列的配置之后, 管理页面的队列的属性没有改变

上面的截图是正确的显示.

后面发现, 如果要修改队列的配置需要先将原有的队列删除, 然后重启项目, 才会重新创建队列. 

在踩坑的道路上, 逐渐成长!!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值