rabbitmq-死信队列

【README】死信队列是什么?

1)死信队列:当消息在一个队列中变成死信之后,它能被重新发送到另一个交换机中,这个交换机被称为DLX(Dead-Letter-Exchange-DLX , 死信交换机);绑定DLX的队列被称之为死信队列;
2)消息变成死信的原因有三个;
消息被拒绝;
消息过期;
队列达到最大长度;

 

【1】如何配置死信队列

1)首先死信队列是相对于正常业务队列而言的;

如   白条还款队列为业务队列, 当该队列有消息过期或被消费者拒绝或队列达到最大长度,则这些消息会被转发到私信队列; 又死信队列通常情况下通过 路由键进行转发,所以需要在死信队列前加一个交换机(俗称死信交换机);

2)要想使用死信队列,必须声明死信交换机,可以在声明正常业务队列的时候设置  正常业务队列对应的死信交换机(需要注意这个映射关系),如下:

/* 2-声明正常队列时,配置其对应死信队列 */ 
Map<String, Object> agruments = new HashMap<String, Object>();
agruments.put("x-dead-letter-exchange", DLX_EXCHANGE); 
//这个agruments属性,要设置到声明队列上
channel.queueDeclare(NORM_QUEUE, true, false, false, agruments);

【2】死信队列荔枝

【2.1】 声明队列,交换机

step1)声明正常业务队列,正常业务交换机,定义正常业务路由键,以及三者间的绑定; 同时,在声明正常业务队列时,一定要设置其 死信交换机(DLX_EXCHANGE),作为属性传入声明方法;

step2)声明死信队列,死信交换机(DLX_EXCHANGE), 定义死信队列接收的路由键(#表示所有),以及三者间的绑定;

/**
 * 声明正常队列+交换机;声明死信队列+交换机   
 */
public class DlxDeclare {
	public static final String POSTFIX = "_tr1";
	/**
	 * 正常队列
	 */
	public static final String NORM_QUEUE = "norm_queue" + POSTFIX;
	/**
	 * 正常交换机 
	 */
	public static final String NORM_EXCHANGE = "norm_exchange" + POSTFIX;
	/**
	 * 正常路由键
	 */
	public static final String NORM_ROUTE = "dlx.save" + POSTFIX;
	/**
	 * 死信队列
	 */
	public static final String DLX_QUEUE = "dlx_queue" + POSTFIX; 
	/**
	 * 死信交换机
	 */
	public static final String DLX_EXCHANGE = "dlx_exchange" + POSTFIX;
	/**
	 * 死信队列路由键-#-所有键 
	 */
	public static final String DLX_ROUTE = "#"; 
	
	public static void main(String[] args) throws Exception {
		/* 获取连接*/
		Connection conn = RBConnectionUtil.getConn();
		// 创建信道 
		Channel channel = conn.createChannel();
		
		/*1-声明正常交换机*/
		channel.exchangeDeclare(NORM_EXCHANGE, BuiltinExchangeType.DIRECT);
		
		/* 2-声明正常队列时,配置其对应死信队列 */ 
		Map<String, Object> agruments = new HashMap<String, Object>();
        agruments.put("x-dead-letter-exchange", DLX_EXCHANGE); 
        //这个agruments属性,要设置到声明队列上
        channel.queueDeclare(NORM_QUEUE, true, false, false, agruments);
        
        /* 3-绑定正常交换机,正常队列和路由键  */  
        channel.queueBind(NORM_QUEUE, NORM_EXCHANGE, NORM_ROUTE);
        
        /*4-声明死信交换机,死信队列,并绑定两者*/  
        channel.exchangeDeclare(DLX_EXCHANGE, BuiltinExchangeType.TOPIC, true, false, null);
        channel.queueDeclare(DLX_QUEUE, true, false, false, null);
        channel.queueBind(DLX_QUEUE, DLX_EXCHANGE, DLX_ROUTE);
	}
}

【2.2】生产者

1)我们把消息的 ttl 设置为10秒,即该消息10秒内没有被成功消费,则消息转发到死信队列;

/**
 * 死信消息生产者  
 */
public class DlxProducer {
	
	public static void main(String[] args) throws Exception {
		/* 获取连接*/
		Connection conn = RBConnectionUtil.getConn();
		// 创建信道 
		Channel channel = conn.createChannel();
		
		AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
        .expiration("10000") // 设置消息的ttl 
        .build();
		
		/* 发送消息 */  
		long temp = System.currentTimeMillis();
		for (int i = 1; i <= 20; i++) { 
			String msg = "我是 msg_norm消息,序号=" + (temp+i) + "时间=" + MyDateUtil.getNow(); 
			channel.basicPublish(DlxDeclare.NORM_EXCHANGE, DlxDeclare.NORM_ROUTE, properties, msg.getBytes("UTF-8")); 
			System.out.println("生产者发送消息" + msg); 
			Thread.sleep(10);
		} 
		/* 关闭连接和信道 */ 
		channel.close();
		conn.close(); 
	}
}

【3】效果

1)生产者把消息发送到正常交换机 norm_exchange_tr1

2)10秒后,由于没有消费,消息被转发到死信队列 dlx_queue_tr1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值