ActiveMQ学习笔记-分发策略
来源:互联网 发布:linux 启动命令模式 编辑:程序博客网 时间:2024/05/18 00:17
异步发送
ActiveMQ默认的发送模式是异步发送,如果我们使用场景是非事务类型或者需要持久化消息,允许少量的消息丢失的话,推荐使用异步发送。同步发送需要增加ack的确认,这样子会增大时延和系统消耗。
cf = new ActiveMQConnectionFactory("tcp://locahost:61616?jms.useAsyncSend=true");
((ActiveMQConnectionFactory)connectionFactory).setUseAsyncSend(true);
((ActiveMQConnection)connection).setUseAsyncSend(true);
分发策略
可插拔的分发策略仅仅能使用在话题上,队列的消息分发策略比较固定,轮询(默认)或者粘性顺序,同时我们也应该了解prefetch的数值的意义prefetch。
默认的prefetch值是十分大的,默认的分发策略总是尽可能的填满prefetch的缓冲区。
这里存在很多的用例且有时候默认的配置并不是很好的工作;比如你发送了很少数量的消息,但是broker要等到一定大数量的消息才发往一个消费者,同时每个消息的处理都需要消耗一定的时间,那么大量的消息将会增加处理的时间。
strictOrderDispatch表示在直到当前消费者的prefetch缓冲区满了之后才选择下一个消费者进行消息的分发。
<policyEntry queue=">" strictOrderDispatch="false" />
话题的分发策略
org.apache.activemq.broker.region.policy.DispatchPolicy类的实现是话题分发的具体策略实现。默认的分发策略是org.apache.activemq.broker.region.policy.SimpleDispatchPolicy,而network 中的分发策略是将消息往优先级高的进行发送org.apache.activemq.broker.region.policy.PriorityNetworkDispatchPolicy 。
<destinationPolicy> <policyMap> <policyEntries> <policyEntry topic="FOO.>"> <dispatchPolicy> <roundRobinDispatchPolicy /> </dispatchPolicy> <subscriptionRecoveryPolicy> <lastImageSubscriptionRecoveryPolicy /> </subscriptionRecoveryPolicy> </policyEntry> <policyEntry topic="ORDERS.>"> <dispatchPolicy> <strictOrderDispatchPolicy /> </dispatchPolicy> <!-- 1 minutes worth --> <subscriptionRecoveryPolicy> <timedSubscriptionRecoveryPolicy recoverDuration="60000" /> </subscriptionRecoveryPolicy> </policyEntry> <policyEntry topic="PRICES.>"> <!-- lets force old messages to be discarded for slow consumers --> <pendingMessageLimitStrategy> <constantPendingMessageLimitStrategy limit="10"/> </pendingMessageLimitStrategy> <!-- 10 seconds worth --> <subscriptionRecoveryPolicy> <timedSubscriptionRecoveryPolicy recoverDuration="10000" /> </subscriptionRecoveryPolicy> </policyEntry> <policyEntry tempTopic="true" advisoryForConsumed="true" /> <policyEntry tempQueue="true" advisoryForConsumed="true" /> </policyEntries> </policyMap></destinationPolicy>
消息游标
使用ActiveMQ会遇到的一个共同的问题就是非持久化消息会耗尽内存缓冲区。
ActiveMQ5.0.0开始,新的内存模型允许我们将消息缓存在磁盘存储页面中,同时也可以直接将消息从生产者传递到消费者(在消息已经持久化后)。
游标类型
ActiveMQ 5.0的有两种游标可以选择
- VM Cursor
- File based Cursor
VM Cursor
速度快,但是在处理慢消费者的时候存在缺点
File based Cursor
File based Cursor是从VM Cursor中派生出来的,当broker达到内存限制的时候,能够将消息分页存储到磁盘中,适用消息存储十分慢但是消费处理十分快的场景。
Paging for Non-Persistent Messages
非持久化消息直接把消息传送游标去。
配置游标
默认使用存储游标,可以为不同的队列配置不同的游标策略。
话题订阅
有效的订阅类型是vmCursor,fileCursor,有效的持久化订阅游标类型是storeDurableSubscriberCursor,storeDurableSubscriberCursor和fileDurableSubscriberCursor,默认是storeDurableSubscriberCursor。
<destinationPolicy> <policyMap> <policyEntries> <policyEntry topic="org.apache.>" producerFlowControl="false" memoryLimit="1mb"> <dispatchPolicy> <strictOrderDispatchPolicy /> </dispatchPolicy> <deadLetterStrategy> <individualDeadLetterStrategy topicPrefix="Test.DLQ." /> </deadLetterStrategy> <pendingSubscriberPolicy> <vmCursor /> </pendingSubscriberPolicy> <pendingDurableSubscriberPolicy> <vmDurableCursor/> </pendingDurableSubscriberPolicy> </policyEntry> </policyEntries> </policyMap></destinationPolicy>
队列的游标类型有 storeCursor, vmQueueCursor 和 fileQueueCursor,默认是storeCursor。
<destinationPolicy> <policyMap> <policyEntries> <policyEntry queue="org.apache.>"> <deadLetterStrategy> <individualDeadLetterStrategy queuePrefix="Test.DLQ."/> </deadLetterStrategy> <pendingQueuePolicy> <vmQueueCursor /> </pendingQueuePolicy> </policyEntry> </policyEntries> </policyMap> </destinationPolicy>
优化确认
ActiveMQ支持确认一个范围内的消息在单个批量操作,这个特性默认是关闭的,开启这个特性会减少broker的负载,可以提升某些情况下系统的吞吐量。
cf = new ActiveMQConnectionFactory("tcp://locahost:61616?jms.optimizeAcknowledge=true");
((ActiveMQConnectionFactory)connectionFactory).setOptimizeAcknowledge(true);
((ActiveMQConnection)connection).setOptimizeAcknowledge(true);
setOptimizeAcknowledgeTimeOut用于设置优化确认的超时时间,默认是300毫秒,0表示不启用该特性。
生产者流量控制
ActiveMQ4.0生产者的流量控制使用TCP的流量控制,这个策略是十分有效的但是在多个生产者和消费者之间共享同一个connection可能会导致死锁。
ActiveMQ5.0以来,我们可以为每一个生产者配置共享的connection而无需suspend整个connection,流量控制意味着当broker检测到内存达到极限,或者文件存储满了,能够让消息的产生慢下来,阻塞生产者知道资源可用,或者接收到JMSException,这些信息我们是配置在节点systemUsage中。
值得注意的是默认的systemUsage配置在memoryLimit或者是systemUsage 达到极限时候是会阻塞生产者的,有时候这会让人误解为生产者被挂起了,实际上消费者只是在等待资源可用。
- 同步发送消息将会自动启用流量控制,除非你开启了useAsyncSend特性
- 在开启了useAsyncSend特性后,内存达到限制后我们将不会接收到任何通知,我们需要配置ProducerWindowSize 用于在内存达到限制后启用流量控制
ProducerWindowSize是生产者在接收到ack之前往broker发送最大的字节数限制
ActiveMQConnectionFactory connctionFactory = ...connctionFactory.setProducerWindowSize(1024000);
或者我们在broker中的内存达到限制的时候通知到,我们可以配置alwaysSyncSend特性。
<destinationPolicy> <policyMap> <policyEntries> <policyEntry topic="FOO.>" producerFlowControl="false"/> </policyEntries> </policyMap></destinationPolicy>
Producer Flow Control 如何工作
通过往生产者发送ack通知生产者当前的windows 大小的数量已经处理,可以继续发送下一个windowSize。
优势
一个好的生产者将会等到返回ack后再继续发送消息从而避免流量泛滥。
Configure Client-Side Exceptions
当broker资源不足时候,将send()的阻塞操作替代微抛出异常也是选项之一。将sendFailIfNoSpace属性配置为true,那么broker将会抛出javax.jms.ResourceAllocationException异常,并传播到客户端。
这样子send操作就不会被挂住,而是捕获到异常后再继续重试。下面配置的单位是毫秒
<systemUsage> <systemUsage sendFailIfNoSpaceAfterTimeout="3000"> <memoryUsage> <memoryUsage limit="20 mb"/> </memoryUsage> </systemUsage></systemUsage>
<systemUsage> <systemUsage> <memoryUsage> <memoryUsage limit="64 mb" /> </memoryUsage> <storeUsage> <storeUsage limit="100 gb" /> </storeUsage> <tempUsage> <tempUsage limit="10 gb" /> </tempUsage> </systemUsage></systemUsage>
时序
有时候保持话题消费者的消费顺序是很有必要的,broker可以保证同一个生产者发送的消息的顺序,但是对于多线程和异步处理,消息从不同到的生产者达到不同消费者的顺序是不同的
比如生产P和Q,发送消息P1,P2,P3,和Q发送Q1,Q2,消费者可能接收到的消息是
consumer1: P1 P2 Q1 P3 Q2consumer2: P1 Q1 Q2 P2 P3
total Orrdering保证了每一个消费所见的消息的顺序都是同样的,但是这样子可能会带来性能上的消耗,但是对于事务类型系统这还是很重要的。
consumer1: P1 P2 Q1 P3 Q2consumer2: P1 P2 Q1 P3 Q2
<destinationPolicy> <policyMap> <policyEntries> <policyEntry topic=">"> <dispatchPolicy> <strictOrderDispatchPolicy/> </dispatchPolicy> </policyEntry> </policyEntries> </policyMap></destinationPolicy>
- ActiveMQ学习笔记-分发策略
- Apache ActiveMQ 高级应用 - 自定义分发策略
- 事件分发学习笔记
- Jms---ActiveMQ学习笔记
- activeMQ学习笔记一
- ActiveMQ学习笔记
- activeMQ学习笔记
- Activemq学习笔记--Queue
- ActiveMQ学习笔记
- ActiveMQ学习笔记(上)
- ActiveMQ学习笔记(中)
- JMS-ActiveMQ学习笔记
- 学习笔记-ActiveMQ
- ActiveMQ入门学习笔记
- ActiveMQ学习笔记-入门教程
- ActiveMQ学习笔记01
- ActiveMQ学习笔记
- ActiveMQ开篇学习笔记
- 数字1的数量
- Linux shell 脚本学习攻略9
- java防止帐号重复登录、后登入用户踢前登入用户
- zoj浙大acm题目分类整理
- 勒索蠕虫-WanaCrypt0r(比特币病毒)防治攻略和事件全回顾
- ActiveMQ学习笔记-分发策略
- React Native实现验证码倒计时功能
- LeetCode 19 Remove Nth Node From End of List(二级指针)
- 【BFS】HDU 2612 Find a way
- redhat6-64位操作系统下安装mysql-5.7.18过程
- eclipse运行jsp文件右键 runconfig
- Atlantis HDU
- CDOJ24_8球胜负
- 六角网格相关算法