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.开头+原来的队列名字的死亡队列,
这时候原队列显示改消息已经被消费了,其实是发送到死亡队列里面去了