消息再传递及未传递的消息 消息有可能传递失败(比如相关的事务发生回滚)。失败的消息将退回到队列中准备重新传递。这样就会出现 一种情况,就是同一个消息会被反复的传递而总不成功,以至于使系统处于忙的状态。 对于这样的消息我们有两种处理方法: 延迟再传递 这种方法是让消息再次传递时有一定的时间延迟,这样客户端就有机会从故障中恢复,同时网络连接和CPU资源 也不致于被过度占用。 死信(Dead Letter)地址 这种方法是规定一个死信地址,如果消息再被反复传递达到一定次数时,就会从原有队列中删除,转到这个 死信地址中。这样消息就不会永远地重复传递了。 以上两种方法可以合理搭配使用,使解决方案更加灵活。
延迟再传递 延迟再传递对于时常出现故障或回滚的客户端十分有用。如果没有延迟,整个系统可能会处于一种”疯狂“的状态。 就是消息被传递、回滚、再传递,这样反复不间断地进行着,将宝贵的CPU和网络资源占用。
延迟再传递的配置 延迟再传递的配置在地址设定内(address-setting): <!-- delay redelivery of messages for 5s --> <address-setting match="jms.queue.exampleQueue"> <redelivery-delay>5000</redelivery-delay> </address-setting> 如果定义了redelivery-delay,ActiveMQ在再传递之前等待所定义的时间。 默认是没有延时的(即redelivery-delay的值是0)。 可以使用通配符为一组地址定义再传递的延迟(参见)。
例子 参见 。这是一个JMS应用中配置延迟再传递的例子。
死信地址 通过定义一个死信地址也可以防止同一个消息被无休止地传递: 当一个消息被重复传递一定次数后,就会从队列中删除并传递到定义好的死信地址中。 这些死信中的消息之后可以转发到某个队列中,以供系统管理员分析处理。 每个ActiveMQ的地址可以有一个死信地址。当一个消息被反复传递达一定次数时,它就会被从队列中删除并送到 死信地址。这些死信消息可以被接收进行分析处理。
配置死信地址 死信地址定义在地址设定中(address-setting): <!-- undelivered messages in exampleQueue will be sent to the dead letter address deadLetterQueue after 3 unsuccessful delivery attempts --> <address-setting match="jms.queue.exampleQueue"> <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address> <max-delivery-attempts>3</max-delivery-attempts> </address-setting> 如果没有定义dead-letter-address,消息在经过 max-delivery-attempts次重复传递后被删除。 默认的重复传递次数为10。将max-delivery-attempts设定为-1 表示无限次重复传递。 例如,对一组地址设置了一个通用的死信地址后,再将其中某个地址的max-delivery-attempts 设定为-1时,那么只有这个地址的再传递次数是无限的。 可以使用通配符对一组地址设定死信地址(参见)。
死信的属性 从死信地址接收到的消息有以下属性: _HQ_ORIG_ADDRESS 这是一个字符串属性,它是该死信消息的原始地址
例子 参见。这个例子给出了在JMS应用中死信的配置与使用。
传递计数的持久化 通常情况下ActiveMQ在一个消息被回滚之前并不更新持久的传递计数(即在消息传递到接收者之前不会更新传递计数)。 大多数情况下消息被接收、通知、然后被忘掉。这样对每一个消息的传递都要更新一次持久的 传递计数,会显著降低系统的性能。 介是如果在消息传递之前不进行持久传递计数的更新,服务器一旦发生故障而崩溃,就会造成消息可能被传递出去而传递 计数却没有正确反映出传递的結果。在恢复阶段,服务器将错误地将该消息的redelivered设为 false而不是true 这样是不符合严格的JMS要求的。因此ActiveMQ允许在消息传递前更新传递计数。但是默认不这样做,目的是优先考虑 了它对性能的影响。 要想打开传递计数更新功能,将activemq-configuration.xml文件中的 persist-delivery-count-before-delivery设为true即可: <persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery>