rabbitmq死信队列

1、消息变成死信的几种情况

  • 消息被拒绝(basic.reject / basic.nack),并且requeue = false
  • 消息TTL过期
  • 队列达到最大长度

2、核心代码

以下内容基于上一篇springboot整合rabbitmq

2.1 添加死信队列、死信队列与短信队列绑定

RabbitConfig

package com.mine.config;

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

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
	// 死信队列 交换机标识符
	public static final String DEAD_LETTER_EXCHANGE_KEY = "x-dead-letter-exchange";

	// 死信队列交换机绑定键标识符
	public static final String DEAD_LETTER_ROUTING_KEY = "x-dead-letter-routing-key";

	// 短信死信交换机
	public static final String EXCHANGE_DEAD_SMS = "dead.sms";

	// 死信队列
	public static final String QUEUE_DEAD_SMS = "queue_dead_sms";

	// 短信死信路由键
	public static final String ROUTING_KEY_DEAD_SMS = "dead_sms";

	// direct交换机
	public static final String EXCHANGE_DIRECT = "mine.direct";
	// 队列
	public static final String QUEUE_EMAIL = "queue_email";
	public static final String QUEUE_SMS = "queue_sms";
	// routingKey
	public static final String ROUTING_KEY_ALL = "all";
	public static final String ROUTING_KEY_EMAIL = "email";
	public static final String ROUTING_KEY_SMS = "sms";

	// fanout交换机
	public static final String EXCHANGE_FANOUT = "mine.fanout";
	// 队列
	public static final String QUEUE_FANOUT_1 = "queue_fanout_1";
	public static final String QUEUE_FANOUT_2 = "queue_fanout_2";

	// 新建direct交换机
	@Bean
	public DirectExchange directExchange() {
		return new DirectExchange(EXCHANGE_DIRECT);
	}

	// 新建邮件队列
	@Bean
	public Queue queueEmail() {
		return new Queue(QUEUE_EMAIL, true);
	}

	// 新建短信队列
	@Bean
	public Queue queueSms() {
		Map<String, Object> args = new HashMap<String, Object>();
		args.put(DEAD_LETTER_EXCHANGE_KEY, EXCHANGE_DEAD_SMS);
		args.put(DEAD_LETTER_ROUTING_KEY, ROUTING_KEY_DEAD_SMS);
		return new Queue(QUEUE_SMS, true, false, false, args);
	}

	// 绑定邮件队列
	@Bean
	public Binding bindingEmail(DirectExchange directExchange, Queue queueEmail) {
		return BindingBuilder.bind(queueEmail).to(directExchange).with(ROUTING_KEY_EMAIL);
	}

	// 绑定短信队列
	@Bean
	public Binding bindingSms(DirectExchange directExchange, Queue queueSms) {
		return BindingBuilder.bind(queueSms).to(directExchange).with(ROUTING_KEY_SMS);
	}

	// 绑定短信队列ALL
	@Bean
	public Binding bindingSmsAll(DirectExchange directExchange, Queue queueSms) {
		return BindingBuilder.bind(queueSms).to(directExchange).with(ROUTING_KEY_ALL);
	}

	// 绑定邮件队列ALL
	@Bean
	public Binding bindingEmailAll(DirectExchange directExchange, Queue queueEmail) {
		return BindingBuilder.bind(queueEmail).to(directExchange).with(ROUTING_KEY_ALL);
	}

	// 新建fanout交换机
	@Bean
	public FanoutExchange fanoutExchange() {
		return new FanoutExchange(EXCHANGE_FANOUT);
	}

	// 新建fanout队列1
	@Bean
	public Queue queueFanout1() {
		return new Queue(QUEUE_FANOUT_1, true);
	}

	// 新建fanout队列2
	@Bean
	public Queue queueFanout2() {
		return new Queue(QUEUE_FANOUT_2, true);
	}

	// 绑定fanout队列1
	@Bean
	public Binding bindingFanout1(FanoutExchange fanoutExchange, Queue queueFanout1) {
		return BindingBuilder.bind(queueFanout1).to(fanoutExchange);
	}

	// 绑定fanout队列2
	@Bean
	public Binding bindingFanout2(FanoutExchange fanoutExchange, Queue queueFanout2) {
		return BindingBuilder.bind(queueFanout2).to(fanoutExchange);
	}

	// 新建短信死信交换机
	@Bean
	public DirectExchange deadSmsExchange() {
		return new DirectExchange(EXCHANGE_DEAD_SMS);
	}

	// 新建短信死信队列
	@Bean
	public Queue queueDeadSms() {
		return new Queue(QUEUE_DEAD_SMS, true);
	}

	// 绑定短信死信队列
	@Bean
	public Binding bindingDeadSms(DirectExchange deadSmsExchange, Queue queueDeadSms) {
		return BindingBuilder.bind(queueDeadSms).to(deadSmsExchange).with(ROUTING_KEY_DEAD_SMS);
	}
}

2.2 修改短信消费者

SmsConsumer

package com.mine.consumer;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class SmsConsumer {

	@RabbitListener(queues = "queue_sms")
	public void process(Message message, Channel channel) throws Exception {
		// 获取消息Id,用消息ID做业务判断
		String messageId = message.getMessageProperties().getMessageId();
		String content = new String(message.getBody(), "UTF-8");
		log.info("接收到短信队列消息:" + content + ",消息ID:" + messageId);
		
		if ("error".equals(content)) {
			// 拒绝消息
			channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
			return;
		}

		// 手动签收
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
	}
}

2.3 添加死信队列消费者

DeadSmsConsumer

package com.mine.consumer;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import com.rabbitmq.client.Channel;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class DeadSmsConsumer {

	@RabbitListener(queues = "queue_dead_sms")
	public void process(Message message, Channel channel) throws Exception {
		// 获取消息Id,用消息ID做业务判断
		String messageId = message.getMessageProperties().getMessageId();
		String content = new String(message.getBody(), "UTF-8");
		log.info("接收到短信死信队列消息:" + content + ",消息ID:" + messageId);

		// 手动签收
		channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
	}
}

3、测试

分别发送【message】和【error】消息,查看rabbitmq控制台和代码日志。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值