ActiveMQ Redelivery Policy(消息重发策略)

转载 2015年11月18日 15:39:49
官方文档:http://activemq.apache.org/redelivery-policy.html
在事务控制里抛出异常,txManager会进行rollback处理.(在activeMQ里,消息默认会redelivery到客户端6次,如果继续异常,消息会放到deadletter queue里(ActiveMQ.DLQ))。

在以下三种情况中,消息会被再次传送给消费者:

1.在使用事务的Session中,调用rollback()方法;

2.在使用事务的Session中,调用commit()方法之前就关闭了Session;

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

可以通过设置ActiveMQConnectionFactoryActiveMQConnection来定制想要的再次传送策略。

当消息被再次投递到客户端时的详细信息在 Message Redelivery and DLQ Handling 章节能找到详细的说明。
你可以在ActiveMQConnectionFactory 或ActiveMQConnection类中配置RedeliveryPolicy属性,用来定义重传策略的具体细节。
您可以使用Java代码,Spring配置或配置URI字符串来定义重传策略。

可用的属性

 属性 默认值 说明 
 collisionAvoidanceFactor  0.15  设置防止冲突范围的正负百分比,只有启用useCollisionAvoidance参数时才生效。也就是在延迟时间上再加一个时间波动范围。
 maximumRedeliveries  6  最大重传次数,达到最大重连次数后抛出异常。为-1时不限制次数,为0时表示不进行重传。
 maximumRedeliveryDelay  -1  最大传送延迟,只在useExponentialBackOff为true时有效(V5.5),假设首次重连间隔为10ms,倍数为2,那么第二次重连时间间隔为 20ms,第三次重连时间间隔为40ms,当重连时间间隔大的最大重连时间间隔时,以后每次重连时间间隔都为最大重连时间间隔。
 initialRedeliveryDelay  1000L  初始重发延迟时间
 redeliveryDelay  1000L  重发延迟时间,当initialRedeliveryDelay=0时生效(v5.4)
 useCollisionAvoidance  false  启用防止冲突功能,因为消息接收时是可以使用多线程并发处理的,应该是为了重发的安全性,避开所有并发线程都在同一个时间点进行消息接收处理。所有线程在同一个时间点处理时会发生什么问题呢?应该没有问题,只是为了平衡broker处理性能,不会有时很忙,有时很空闲。
 useExponentialBackOff  false  启用指数倍数递增的方式增加延迟时间。
 backOffMultiplier  5  重连时间间隔递增倍数,只有值大于1和启用useExponentialBackOff参数时才生效。

官方文档有些参数功能说得不是很清楚,如collisionAvoidanceFactor,那只能查看源代码了,
可以查看org.apache.activemq.ActiveMQMessageConsumer类中的rollback()方法:

public void rollback() throws JMSException {

......

final int currentRedeliveryCount = lastMd.getMessage().getRedeliveryCounter(); if (currentRedeliveryCount > 0) { redeliveryDelay = redeliveryPolicy.getNextRedeliveryDelay(redeliveryDelay); } else { redeliveryDelay = redeliveryPolicy.getInitialRedeliveryDelay(); }

......

}

先获取重发次数,如果是第一次重发则延迟时间为initialRedeliveryDelay,如果不是第一次重发则延迟时间为redeliveryDelay = redeliveryPolicy.getNextRedeliveryDelay(redeliveryDelay);这里的redeliveryDelay参数是前一次重发的延迟时间。

public long getNextRedeliveryDelay(long previousDelay) { long nextDelay; if (previousDelay == 0) { nextDelay = redeliveryDelay; } else if (useExponentialBackOff && backOffMultiplier > 1) { nextDelay = (long) (previousDelay * backOffMultiplier); if(maximumRedeliveryDelay != -1 && nextDelay > maximumRedeliveryDelay) { // in case the user made max redelivery delay less than redelivery

delay for some reason. nextDelay = Math.max(maximumRedeliveryDelay, redeliveryDelay); } } else { nextDelay = previousDelay; } if (useCollisionAvoidance) { /* * First random determines +/-, second random determines how far to * go in that direction. -cgs */ Random random = getRandomNumberGenerator(); double variance = (random.nextBoolean() ? collisionAvoidanceFactor :

-collisionAvoidanceFactor) * random.nextDouble(); nextDelay += nextDelay * variance; } return nextDelay; }

计算下一次重发延迟时间时,当启用指数倍数增长方式useExponentialBackOff=true,且增长倍数backOffMultiplier > 1时,下一次延迟时间为previousDelay * backOffMultiplier,这里的previousDelay为前一次延迟重发的时间。

collisionAvoidanceFactor这个参数spring中是不能直接注入的,注入方法为:

public void setCollisionAvoidancePercent(short collisionAvoidancePercent) { this.collisionAvoidanceFactor = collisionAvoidancePercent * 0.01d; }

这里的collisionAvoidancePercent是个短整形,比如15,则方法直接计算为15%。在spring中注入方式为:

<property name="collisionAvoidancePercent" value="15" />

如果useCollisionAvoidance=true,则nextDelay += nextDelay * variance;这里的variance是一个随机的正负值,Random.nextDouble()的范围是:0.0d到1.0d,当redeliveryDelay=1000L,collisionAvoidanceFactor值为0.15时,那么正负variance的范围就是:-0.15到+0.15,那么最后nextDelay的值范围就是:1000+1000*-15%~1000+1000*15%,即在850~1150范围内波动。

这里延时有两个参数没看明白用途,正常一个参数就可以了:关于initialRedeliveryDelay和redeliveryDelay。

从测试结果看:

当initialRedeliveryDelay>0,redeliveryDelay>0时,延时时间是按initialRedeliveryDelay的,包括第一次。

当initialRedeliveryDelay=0,redeliveryDelay>0时,延时时间第一次重发时却是按DefaultMessageListenerContainer的receiveTimeout和recoveryInterval参数的值进行重发的,以后才是按redeliveryDelay递增时间重发的。

且:

当receiveTimeout小于recoveryInterval时,第一次延迟时间为receiveTimeout时间,

当receiveTimeout大于recoveryInterval时,第一次延迟时间为recoveryInterval时间。


http://windows9834.blog.163.com/blog/static/2734500420131195224532/

设置ActiveMQ的Redelivery Policy

Redelivery Policy Detail on when messages are redelivered to a client can be found in the Message...
  • zxbcjdx
  • zxbcjdx
  • 2011年09月21日 17:53
  • 2412

ActiveMQ的消息重发机制

本文以ActiveMQ最新的5.10版本为准。        大家知道,JMS规范中,Message消息头接口中有setJMSRedelivered(boolean redelivered)和getJ...
  • manzhizhen
  • manzhizhen
  • 2016年09月21日 13:04
  • 2649

ActiveMQ中的消息重发时间间隔和重发次数吗?

首先,我们得大概了解下,在哪些情况下,ActiveMQ服务器会将消息重发给消费者,这里为简单起见,假定采用的消息发送模式为队列(即消息发送者和消息接收者)。       1.如果消息接收者在处理...
  • xcw931924821
  • xcw931924821
  • 2016年10月11日 16:42
  • 3038

ActiveMQ单个对列配置重发数

Redelivery Policy Detail on when messages are redelivered to a client can be found in the Messa...
  • lulongzhou_llz
  • lulongzhou_llz
  • 2015年03月16日 15:45
  • 1366

Spring ActiveMQ 整合(二): 重发机制(消息发送失败后的重新发送)

假如现在我手里有一个很重要的消息的,想要发给一个人,但是很不幸,消息发送失败了。这时候怎么办呢怎么解决这种尴尬的情况,这时候我们可以利用activeMQ的 消息重发机制(RedeliveryPoli...
  • dly1580854879
  • dly1580854879
  • 2017年03月30日 16:45
  • 6096

ActiveMQ Redelivery Policy(讯息重发策略)

官方文档:http://activemq.apache.org/redelivery-policy.html 在事务控制里抛出异常,txManager会进行rollback处理.(在activeMQ...
  • luxianping
  • luxianping
  • 2016年03月16日 06:27
  • 750

mule使用jms 进行事务回滚(rollback) 和消息重发(redelivery)

这个示例演示 使用jms 进行事务(rollback) 和消息重发(redelivery) JMS报文 在事务中抛出一个异常 示例中报文随即被异常回滚策略组件( Rollback Exceptio...
  • ke_weiquan
  • ke_weiquan
  • 2016年07月12日 11:40
  • 392

ActiveMQ的消息重发策略和DLQ处理

在以下三种情况中,ActiveMQ消息会被重发给客户端/消费者:  1.使用一个事务session,并且调用了rollback()方法;  2.一个事务session,关闭之前调用了commit;...
  • zlfprogram
  • zlfprogram
  • 2017年05月19日 10:52
  • 2267

ActiveMQ的消息重发策略和DLQ处理

ActiveMQ的消息重发策略和DLQ处理,自动丢弃过期消息,将非持久消息(non-persistent messages)放入死信队列...
  • gaolu
  • gaolu
  • 2013年12月09日 12:56
  • 2343

ActiveMQ消息重发策略和DLQ处理(转载)

文章源地址:http://sharong.iteye.com/blog/1987171 在以下三种情况中,ActiveMQ消息会被重发给客户端/消费者: 1.使用一个事务session,并且调...
  • amienshxq
  • amienshxq
  • 2014年11月15日 08:53
  • 334
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ActiveMQ Redelivery Policy(消息重发策略)
举报原因:
原因补充:

(最多只允许输入30个字)