一、简介
在使用activemq消息中间件进行消息队列传输时,总会由于各种原因导致消息失败。
一个经典的场景是一个生成者向Queue中发消息,里面包含了一组邮件地址和邮件内容。而消费者从Queue中将消息一条条读出来,向指定邮件地址发送邮件。消费者在发送消息的过程中由于种种原因会导致失败,比如网络超时、当前邮件服务器不可用等。这样我们就希望建立一种机制,对于未发送成功的邮件再重新发送,也就是重新处理。重新处理超过一定次数还不成功,就放弃对该消息的处理,记录下来,继续对剩余消息进行处理。
ActiveMQ为我们实现了这一功能,叫做ReDelivery(重新投递)。当消费者在处理消息时有异常发生,会将消息重新放回Queue里,进行下一次处理。当超过重试次数时,消息会被放置到一个特殊的Queue中,即Dead Letter Queue,简称DLQ,用于进行后续分析。
二、RedeliveryPolicy属性介绍
消息重发机制RedeliveryPolicy 有几个属性如下:
RedeliveryPolicy redeliveryPolicy= new RedeliveryPolicy(); //是否在每次尝试重新发送失败后,增长这个等待时间 redeliveryPolicy.setUseExponentialBackOff(true); //重发次数,默认为6次 这里设置为10次 redeliveryPolicy.setMaximumRedeliveries(10); //重发时间间隔,默认为1秒 redeliveryPolicy.setInitialRedeliveryDelay(1); //第一次失败后重新发送之前等待500毫秒,第二次失败再等待500 * 2毫秒,这里的2就是value redeliveryPolicy.setBackOffMultiplier(2); //是否避免消息碰撞 redeliveryPolicy.setUseCollisionAvoidance(false); //设置重发最大拖延时间-1 表示没有拖延只有UseExponentialBackOff(true)为true时生效 redeliveryPolicy.setMaximumRedeliveryDelay(-1);
三、什么情况下会触发消息重发
1.在使用事务的Session中,调用rollback()方法;
2.在使用事务的Session中,调用commit()方法之前就关闭了Session;
3.在Session中使用CLIENT_ACKNOWLEDGE签收模式或者INDIVIDUAL_ACKNOWLEDGE模式,并且调用了recover()方法。
可以通过设置ActiveMQConnectionFactory来定制想要的再次传送策略。
4.消息接收的时候抛出异常
需要注意的是:使用手动签收模式,如果客户端没有调用message.acknowledge()方法是不会立刻重发消息的,只有当前Coustomer重启时才能重新接受消息