ActiveMq optimizeACK & prefetch

1、prefeth&optimizeACK

prefeth:consumer批量获取消息

optimizeACK :broker 延迟确认消费的消息。

client端在消费消息后暂且不发送ACK,而是把它缓存下来(pendingACK),等到这些消息的条数达到一定阀值时,只需要通过一个ACK指令把它们全部确认;这比对每条消息都逐个确认,在性能上要提高很多。

2、optimizeACK=true(开启优化ACK)

 prefetch>0(必须):broker push message to consumer
当prefetch > 0时,broker端将会批量push给client 一定数量的消息(<= prefetch),client端会把这些消息(unconsumedMessage)放入到本地的队列中,只要此队列有消息,那么receive方法将会立即返回,当一定量的消息ACK之后,broker端会继续批量push消息给client端

消息确认时机:注:单情景举例 a、b 、c情景不重叠互相不满足。

a、optimizeAcknowledge

producer一次性发送消息 且 prefetchSize >消息总数 > prefetchSize * 0.65    当客户端消费过的消息超过prefetchSize * 0.65 则发送一次ACK 确认prefetchSize * 0.65消费过的消息 ,(prefetchSize -消息总数)的消息一直pending

ex:prefetchSize=100 ,prefetchSize * 0.65 = 65,producer发送消息总数50(不大于65)则不触发消息确认 50条消息一直pending

prefetchSize=100 ,prefetchSize * 0.65 = 65,producer发送消息总数66(大于65)则触发消息确认 65条消息  1条消息一直pending

b、optimizeAcknowledgeTimeOut

ex:producer一次性发送50条消息, 且未超过optimizeAcknowledgeTimeOut 则50条消息一直pending

producer一次性发送50条消息(A-beginTime),消费30条后(A-endTime)消费时长超过optimizeAcknowledgeTimeOut 则发送ACK(B-beginTime)。剩余20条消息消费完成后(B-endTime)消费时长未超过optimizeAcknowledgeTimeOut。则20条消息一直pending。

c、optimizedAckScheduledAckInterval:每隔optimizedAckScheduledAckInterval就发送ACK

3、optimizeACK=false(关闭优化ACK)

prefetch=0:consumer pull message from broker

prefetch>0:broker push message to consumer

================================================================================================

什么是prefetch

prefetch即在activemq中消费者预获取消息数量,重要的调优参数之一。当消费者存活时,broker将会批量push prefetchSize条消息给消费者,消费者也可以配合optimizeAcknowledge来批量确认它们。由于broker批量push消息给消费者,提高了网络传输效率,此值默认为1000。

通过上述,我们对broker消息转发机制的了解,可以知道,broker端将会根据consumer指定的prefetchSize来决定pendingBuffer的大小,prefetchSize越大,broker批量发送的消息就会越多,如果消费者消费速度较快,再配合optimizeAck,这将是相对完美的消息传送方案。

不过,prefetchSize也会带来一定的问题,在Queue中(Topic中没有效果),broker将使用“轮询”的方式来平衡多个消费者之间的消息传送数量。如果消费者消费速度较慢,而且prefetchSize较大,这将不利于消息量在多个消费者之间平衡。通常情况下,如果consumer数量较多,或者消费速度较慢,或者消息量较少时,我们应该设定prefetchSize为较小的值。

上面的内容摘抄:http://blog.csdn.net/asdfsadfasdfsa/article/details/53501723

其实,prefetchSize与optimizeACK策略关系密切,将在下一个介绍optimizeACK的小节中详细说明。

什么是optimizeACK

可优化的消息ACK策略,关系到是否批量确认消息的策略,这个是Consumer端最重要的调优参数之一。optimizeAcknowledge 表示是否开启“优化ACK选项”,当开启optimizeAck策略后,该参数的具体含义和消费端的处理如下:

(1)如果消费端处理消息的时间超过optimizeAcknowledgeTimeOut,消费端会向broker主动确认pending ack里面的消息,即等待确认的消息,这个与prefetch size有很大的关系,如果prefetch size为1,那么broker push到消费端的消息数会是1,那么在当前消息未完成处理的情况下,pending ack肯定是0,所以不会向broker确认消息。但是,假设prefetch size为5,broker推送到消费者的消息是5条,消费端在处理第3条消息的时候,耗时很长,导致5条消息的处理时候早早的超过了optimizeAcknowledgeTimeOut,此时,消费端将会把前面2条已经确认的消息,告诉broker,让broker从队列中删除消息,此时broker发现消费端还可以存放2个消息,又push两条消息到消费端。

(2)除了optimizeAcknowledgeTimeOut这个参数会使消费者触发批量确认消息,还有另一个指标,即,成功消费但待确认的消息数量超过 预取数量prefetchSize * 0.65 时,也会触发消费端自动确认那些待确认的消息

================================================================================================

发送:

1. 重要消息采用默认的同步发送useAsyncSend=false;

2. 加上线程池;

3. 批量发送加上事务。

同步发送采用线程池和事务批量发送的话,本机测试(levelDB持久化) 10W消息12秒发送完比,约8000/S。

 

接收:

1. 加上线程池;

2. 重要消息加上事务,保证一个consumer抛Exception后消息能转发到其它consumer;

3. 不能容忍重复的消息一定要加上去重处理,当consumer没有ACK之前停机一定会发生重复消息且redeliveryCounter=0(这里不知是否没配置对)。可运行activeMQ自己的测试类RedeliveryPolicyTest.java中的testRepeatedRedelivery*方法,在“connection.close()”之前停止运行。

 

消息确认:

1. optimizeAcknowledge:每批次消息消费65%后发送确认,假如某个queue的destination为"queue.test.msg?consumer.prefetchSize=10",客户端在处理完第7条消息时会发送第1~7条消息的ACK。也就是说某个consumer在处理完这10条后停机,后面的3条消息会得不到确认,再开启一个consumer会重新收到这3条且redeliveryCounter=0。

2. optimizeAcknowledgeTimeOut:系统时间 - 前条消息处理时间 > optimizeAcknowledgeTimeOut即发送ACK,如果条件不成立则按optimizeAcknowledge处理。

3. optimizedAckScheduledAckInterval:每隔optimizedAckScheduledAckInterval就发送ACK,如果条件不成立则按optimizeAcknowledge处理===============================================================================================

4、topics

当consumer端消息消费的速率很高(相对于producer生产消息),而且消息的数量也很大时(比如消息源源不断的生产),我们使用optimizeACK + prefetch将会极大的提升consumer的性能。不过反过来:

1) 如果consumer端消费速度很慢(对消息的处理是耗时的),过大的prefetchSize,并不能有效的提升性能,反而不利于consumer端的负载均衡(只针对queue);按照良好的设计准则,当consumer消费速度很慢时,我们通常会部署多个consumer客户端,并使用较小的prefetch,同时关闭optimizeACK,可以让消息在多个consumer间“负载均衡”(即均匀的发送给每个consumer);如果较大的prefetchSize,将会导致broker一次性push给client大量的消息,但是这些消息需要很久才能ACK(消息积压),而且在client故障时,还会导致这些消息的重发。

2) 如果consumer端消费速度很快,但是producer端生成消息的速率较慢,比如生产者10秒钟生成10条消息,但是consumer一秒就能消费完毕,而且我们还部署了多个consumer!!这种场景下,建议开启optimizeACK,但是需要设置的prefetchSize不能过大;这样可以保证每个consumer都能有"活干",否则将会出现一个consumer非常忙碌,但是其他consumer几乎收不到消息。

3) 如果消息很重要,特别是不愿意接收到”redelivery“的消息,那么我们需要将optimizeACK=false,prefetchSize=1既然optimizeACK是”延迟“确认,那么就引入一种潜在的风险:在消息被消费之后还没有来得及确认时,client端发生故障,那么这些消息就有可能会被重新发送给其他consumer,那么这种风险就需要client端能够容忍“重复”消息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值