关闭

activemq 如何开启死信队列

2542人阅读 评论(0) 收藏 举报
分类:
在以下三种情况中,ActiveMQ消息会被重发给客户端/消费者: 
1.使用一个事务session,并且调用了rollback()方法; 
2.一个事务session,关闭之前调用了commit; 

3.在session中使用CLIENT_ACKNOWLEDGE签收模式,并且调用了Session.recover()方法。 

Broker根据自己的规则,通过BrokerInfo命令包和客户端建立连接,向客户端传送缺省发送策略。但是客户端可以使用ActiveMQConnection.getRedeliveryPolicy()方法覆盖override这个策略设置。 
Java代码  收藏代码
RedeliveryPolicy policy = connection.getRedeliveryPolicy();  
policy.setInitialRedeliveryDelay(500);  
policy.setBackOffMultiplier(2);  
policy.setUseExponentialBackOff(true);  
policy.setMaximumRedeliveries(2); 

xml配置如下

一旦消息重发尝试超过重发策略中配置的maximumRedeliveries(缺省为6次)时,会给broker发送一个"Poison ack",通知它,这个消息被认为是一个毒丸(a poison pill),接着broker会将这个消息发送到DLQ(Dead Letter Queue),以便后续分析处理。 


缺省死信队列(Dead Letter Queue)叫做ActiveMQ.DLQ;所有的未送达消息都会被发送到这个队列,以致会非常难于管理。你可以设置activemq.xml文件中的destination policy map的"individualDeadLetterStrategy"属性来修改.


开启死信队列 必需在事物开启的情况下才可以

listen代码如下

public class DefaultMessageListener implements MessageListener {

	private static Logger logger = LoggerFactory.getLogger("activeMQLog");

	private RyzhMessageReceiver receiver;

	public void onMessage(Message message) {
		logger.info("DefaultMessageListener 人员整合 :消费者开始消费");
		ObjectMessage objectMessage = (ObjectMessage) message;
		RyzhMessage ryzhMessage = null;
		try {
			ryzhMessage = (RyzhMessage) objectMessage.getObject();
			receiver.receive(ryzhMessage);
			int a =1/0;
			// 没有报错就确认消息接收
			// logger.info("DefaultMessageListener 人员整合:消费者消费成功1111111111111111111");
			// throw new JMSException("process failed");
			objectMessage.acknowledge();
			logger.info("DefaultMessageListener 人员整合:消费者消费成功");
		} catch (Exception e) {
			logger.error("DefaultMessageListener 人员整合:消费者消费时出现异常 ShcemeId:" + ryzhMessage.getShcemeId(), e);
			throw JmsUtils.convertJmsAccessException(new JMSException(e.getMessage()));
		}
	}

	public RyzhMessageReceiver getReceiver() {
		return receiver;
	}

	public void setReceiver(RyzhMessageReceiver receiver) {
		this.receiver = receiver;
	}

}

发送者代码如下

<span style="color:#666666;">public void send(final RyzhMessage ryzhMessage) {
		// 得到MQ工具类
		RyzhMqHolder hodler = mqHolders.get(ryzhMessage.getShcemeId());
		// 发送信息
		jmsTemplate.setConnectionFactory(cachingProductConnectionFactory);
		jmsTemplate.send(hodler.getDestination(), new MessageCreator() {
			public Message createMessage(Session session) throws JMSException {
				ObjectMessage objectMessage = session.createObjectMessage();
				objectMessage.setObject(ryzhMessage);
				</span><span style="color:#ff0000;">objectMessage.setJMSRedelivered(true);//消息重发</span><span style="color:#666666;">
				return objectMessage;
			}
		});
	}</span>


效果如下图 默认是发送到ActiveMQ.DLQ的死亡队列,修改mq配置之后重启,是发送到以DLQ.开头+原来的队列名字的死亡队列,

这时候原队列显示改消息已经被消费了,其实是发送到死亡队列里面去了


2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:39340次
    • 积分:929
    • 等级:
    • 排名:千里之外
    • 原创:54篇
    • 转载:5篇
    • 译文:0篇
    • 评论:1条
    最新评论