1.消息发送

1.异步发送

消息生产者使用持久(persistent)传递模式发送消息的时候,Producer.send() 方法会被阻塞,直到 broker 发送一个确认消息给生产者,这个确认消息暗示生产者 broker已经成功地将它发送的消息路由到目标目的并把消息保存到二级存储中。这个过程通常称为同步发送。但有一个例外,当发送方法在一个事物上下文中时,被阻塞的是 commit 方法而不是 send 方法。commit 方法成功返回意味着所有的持久消息都以被写到二级存储中。
同步发送持久消息能够提供更好的可靠性,但这潜在地影响了程序的相应速度,因为在接受到 broker 的确认消息之前应用程序或线程会被阻塞。如果应用程序能够容忍一些消息的丢失,那么可以使用异步发送。异步发送不会在受到 broker 的确认之前一直阻塞 Producer.send 方法。如果想启动异步传送可以把 connector uri 的 jms.useAsyncSend 选项设为 true,如下所示:
    tcp://localhost:61616?jms.useAsyncSend=true
从 ActiveMQ 5 开始可以控制异步发送流。也就是说,在受到 broker 的确认应答之前,生产者能够传送消息给 broker 的最大信息量。即使是异步发送消息,生产者也是在收到 broker 的确认应答后才把下一条消息传送给 broker。当使用异步传送的时候,可以设置jms.producerWindowSize(单位为字节)属性,当生产者中等待发送的信息量到达设置的值时,即使没有收到 broker 的应答消息,生产者同样会把这些消息发给 broker。如下面的示例设置:
 
tcp://localhost:61616?jms.useAsyncSend=true&jms.producerWindowSize=1024000

org.apache.activemq.ActiveMQConnectionFactory中引入:

<property
name="useAsyncSend" value="true" />  <!-- false:同步 true:异步 -->

2. ActiveMQ讯息策略

只对Topic有效

DispatchPolcicy:
转发策略

RoundRobinDispatchPolicy

轮询

StrictOrderDispatchPolicy

严格有序

PriorityDispatchPolicy

基于“property”权重对“订阅者”排序

SimpleDispatchPolicy(默认值)

按照当前“订阅者”列表的顺序

SubscriptionRecoveryPolicy: 恢复策略

FixedSizedSubscriptionRecoveryPolicy

保存一定size的消息

FixedCountSubscriptionRecoveryPolicy

保存一定条数的消息

LastImageSubscriptionRecoveryPolicy

只保留最新的一条数据

QueryBasedSubscriptionRecoveryPolicy

符合置顶selector的消息都将被保存

TimedSubscriptionRecoveryPolicy

保留最近一段时间的消息

NoSubscriptionRecoveryPolicy(默认值)

关闭“恢复机制”

PendingMessageLimitStrategy:
消息限制策略(面向Slow Consumer)

ConstantPendingMessageLimitStrategy

保留固定条数的消息

PrefetchRatePendingMessageLimitStrategy

保留prefetchSize倍数条消息

MessageEvictionStrategy: 消息剔除策略(面向Slow Consumer)

OldestMessageEvictionStrategy(默认值)

移除旧消息

OldestMessageWithLowestPriorityEvictionStrategy

旧数据中权重较低的消息,将会被移除

UniquePropertyMessageEvictionStrategy

移除具有指定property的旧消息

PendingSubscriberMessageStoragePolicy: 待消息转存策略(针对非耐久)

vmCursor
(默认值)

将消息转存到基于内存

storeCursor

将消息转存到storeEngine中

fileCursor

将消息转存到临时文件中

PendingSubscriberMessageStoragePolicy: 待消息转存策略(针对耐久)

vmDurableCursor

将消息转存到基于内存

storeDurableSubscriberCursor

将消息转存到storeEngine中

fileDurableSubscriberCursor

将消息转存到临时文件中

只对Queue有效

PendingQueueMessageStoragePolicy:待消息转存策略

vmQueueCursor(默认值)

将消息转存到基于内存

storeCursor

将消息转存到storeEngine中

fileQueueCursor

将消息转存到临时文件中

对Topic和Queue都有效

DeadLetterStrategy:“死信”策略

IndividualDeadLetterStrategy

把DeadLetter放入各自的死信通道中

SharedDeadLetterStrategy(默认值)

将所有的DeadLetter保存在一个共享的队列中

DiscardingDeadLetterStrategy

broker将直接抛弃DeadLeatter

SlowConsumerStrategy:慢速消费者策略

AbortSlowConsumerStrategy

中断慢速消费者

AbortSlowConsumerStrategy

如果慢速消费者最后一个ACK距离现在的时间间隔超过阀值,则中断慢速消费者。

         

3. 消息重发策略

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

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

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

<!--
重发策略 -->

<bean
id="activeMQRedeliveryPolicy" class="org.apache.activemq.RedeliveryPolicy">

<!--重发次数,默认为6次 这里设置为1次 -->

<property
name="maximumRedeliveries" value="4"></property>

<!--重发时间间隔,默认为1秒 -->

<property
name="initialRedeliveryDelay"
value="2000"></property>

</bean>

class="org.apache.activemq.ActiveMQConnectionFactory"中引入:

<property
name="redeliveryPolicy" ref="activeMQRedeliveryPolicy"
/>

org.springframework.jms.listener.DefaultMessageListenerContainer中引入:

<property
name="sessionTransacted" value="true" />

4.消息持久化与非持久化

采用持久传输时,传输的消息会保存到磁盘中(messages
are persisted to disk/database),即“存储转发”方式。先把消息存储到磁盘中,然后再将消息“转发”给订阅者。

采用非持久传输时,发送的消息不会存储到磁盘中。

采用持久传输时,当Borker宕机 恢复后,消息还在。采用非持久传输,Borker宕机重启后,消息丢失。比如,当生产者将消息投递给Broker后,Broker将该消息存储到磁盘中,在Broker将消息发送给Subscriber之前,Broker宕机了,如果采用持久传输,Broker重启后,从磁盘中读出消息再传递给Subscriber;如果采用非持久传输,这条消息就丢失了。

org.springframework.jms.core.JmsTemplate中引入:

<property
name="explicitQosEnabled" value="true" /> <!-- 是否启用下列配置 -->

<property
name="deliveryMode" value="1"/>  <!-- 1:非持久化2:持久化 -->

<property
name="deliveryPersistent" value="false" />   <!-- true:持久化false:非持久化 -->

其中deliveryPersistent写不写均可

5.死信队列

DLQ-死信队列(Dead Letter Queue)用来保存处理失败或者过期的消息.缺省的死信队列是ActiveMQ.DLQ,如果没有特别指定,死信都会被发送到这个队列。默认情况下持久消息过期,会被送到DLQ,非持久消息不会送到DLQ

消息进入死信队列条件:

1.给ActiveMQConnectionFactory配上重发机制;

2.给DefaultMessageListenerContainer配置事务;

在activemq.xml的policyEntries节点中增加如下策略配置。

<policyEntry
queue=">">

<deadLetterStrategy>

<individualDeadLetterStrategy
useQueueForQueueMessages="true"
processNonPersistent="true"

queuePrefix="DLQ." processExpired="true"/>

</deadLetterStrategy>

</policyEntry>

useQueueForQueueMessages:true队列;false主题

processNonPersistent:true非持久化的消息放入死信队列

processExpired:true过期消息放入死信队列

queuePrefix:队列名称前缀, DLQ.+队列名称

6. Consumer特性详解与优化

asyncDispatch(默认为true)

broker端是否允许使用异步转发

alwaysSessionAsync(默认为true)

客户端session是否使用异步转发

maxThreadPoolSize

(默认Integer.MAX_VALUE)

Session异步转发线程池大小,Connection下所有session共享

useDedicatedTaskRunner(默认为false)

为每个session设置单独的线程池

messagePrioritySupported(默认为true)

Consumer是否开启消息权重,即是否支持消息优先级的属性设置

Priority(默认为0)

消费者权重,broker会优先级把消息转发给权重更大的Consumer

prefetchSize(默认为1000)

Broker批量发送prefetchSize条消息给consumer

noLocal(默认为false)

consumer是否接受本地消息,本地消息,就是为同一个connection创建的producer发送的消息

exclusiveConsumer

(仅对Queue有效, 默认值为false)

如果Queue中,有任意一个Consumer是“排他的”,那么消息只会转发给“exclusiveConsumer=true”的消费者;如果全部的消费者都是“排他的”,那么最新创建的consumer将会获取消息

allConsumersExclusiveByDefault

如果此参数为true,那么当前Queue中的所有消费者默认为exclusive

Retroactive

(仅对Topic有效, 默认值为false)

retroactive类型的订阅者可以获取这些原本不属于自己但broker上还保存的旧消息, 如果此订阅者不是durable(耐久的),它可以获取最近发布的一些消息;如果是durable,它可以获取存储器中尚未删除的所有的旧消息

selector (选择器)

Broker通过selector在筛选满足条件的Consumer, 如果你使用了selector,你一定要让全局中所有的selector覆盖所有的消息,或者至少有一个没有selector的consumer

Group(消息分组)(仅对Queue有效)

Producer在发送消息时为多条消息设定group,它们将会被同一个consumer消费

Duplicate(重复消息)

consumer在将消息消费之前,都会检测消息是否重复,对于重复消息,将不会消费而是直接发送poisonAck(毒丸),broker端会将消息直接删除。

7.慢速消费者(Slow
Consumer)

慢速,是相对于producer而言;简单来说,producer不断产生新的消息,broker端在内存中已经积压的足够多(比如cacheLimit已满),但是在转发给某个consumer时,发现此consumer仍然有大量的消息尚没有消费(ACK),broker会认为此consumer是慢速的。

在Queue中,如果已发送(dispatched)但没有消费(unAck)的消息条数 > prefetchSize时,此consumer被标记为Slow。

在Topic中,如果cacheLimit已满,但是需要向此订阅者发送的消息量 >
prefetchSize时,此订阅者被标记为Slow。

简单描述为: 快速的producer生产的消息,不能被消费者及时的消费,而导致在broker端积压。

解决方案:

1) 关闭Slow Consumer

brorker端一旦发现slow consumer,就将它注册到慢速消费者列表中,此后将有额外的线程扫描并关闭它们,其中abortConnection表示,是否关闭底层的transport,默认为false,此时将会通过transport向client端发送一个指令(其中包括consumerId),当client端(Session)接收之后,将会调用consumer.close()方法;如果此值为true,将会导致底层的transport链接被关闭,这是很粗暴的办法,不过如果client端多个consumer共享一个connection的话,会导致所有的consumer被关闭,还是那句话:猪一样的队友,害了整个团队。

<policyEntry queue=">" producerFlowControl="true" memoryLimit="512mb">

<slowConsumerStrategy>

<abortSlowConsumerStrategy abortConnection="false"/>

</slowConsumerStrategy>

</policyEntry>

2) 抛弃旧消息(仅对Topic有效,仅对nondurable订阅者有效)

topic支持支持3种移除策略:

(1) oldestMessageEvictionStrategy表示移除最旧的消息

(2) uniquePropertyMessageEvictionStrategy表示移除根据属性值筛选消息并移除最旧的

(3)
OldestMessageWithLowestPriorityEvictionStrategy表示在旧消息中移除权重最低的。

3) 写入临时文件

       对于Queue而言,支持storeCursor,vmQueueCursor , fileQueueCursor。其中storeCursor是一个“综合”策略,持久化消息使用fileQueueCurosr支持,非持久化消息使用vmQueueCursor支持。vmQueueCursor基于内存,fileQueueCursor表示将数据写入本地临时文件(由tempDataStore决定)。

对于Topic而言,我们也可以根据订阅者的类型,来决定如果处理那些滞留的非持久化消息。

4) offlineDurableSubscriberTimeout

对于durable订阅者,如果订阅者“离线”,那么Broker将会一直保存属于它的消息,因此消息也会以为它而不能删除,导致积压。通常,订阅者离线的时间是无法预估的,有可能此订阅者永远都不会再上线(可能因为durable订阅者本来应该cancel,但是开发者却忘记了),这对broker来说是致命的。我们需要限制durable订阅者离线的时间,如果超过时间,那么订阅者将会被移除,消息也会因此而删除。

<broker name="localhost" offlineDurableSubscriberTimeout="86400000" offlineDurableSubscriberTaskSchedule="3600000">

8. Activemq消息确认机制

optimizeAck表示是否开启“优化ACK”, 只有在为true的情况下,prefetchSize(下文中将会简写成prefetch)以及optimizeAcknowledgeTimeout参数才会有意义, "optimizeAcknowledgeTimeout"选项只能在brokerUrl中配置, 在destinationUri中指定prefetchSize(预获取)选项,
其中brokerUrl参数选项是全局的,如果同时指定,brokerUrl中的参数选项值将会被覆盖;

当consumer端使用MessageListener异步获取消息时: prefetch>=1

当consumer端使用receive()方法同步获取消息时: prefetch>=0

prefetch=0, receive()方法将会首先发送一个PULL指令并阻塞,直到broker端返回消息为止;

prefetch>0, broker端将会批量push给client 一定数量的消息(<=
prefetch),client端会把这些消息(unconsumedMessage)放入到本地的队列中;

ActiveMQ配置策略的更多相关文章

  1. ActiveMQ配置详解

    原文链接 一.消息目的地策略 在节点destinationPolicy配置策略,可以对单个或者所有的主题和队列进行设置,使用流量监控,当消息达到memoryLimit的时候,ActiveMQ会减慢消息 ...

  2. 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)

    你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...

  3. 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)

    从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...

  4. WebLogic域配置策略

    WebLogic域配置策略--手动和模板选项,第一部分 域含有BEA WebLogic Server实例的配置信息.它包含有关服务器.集群和机器的配置信息.域还含有关于资源,例如Java数据库连接(J ...

  5. Spring Cloud Config采用Git存储时两种常用的配置策略

    由于Spring Cloud Config默认采用了Git存储,相信很多团队在使用Spring Cloud的配置中心时也会采用这样的策略.即便大家都使用了Git存储,可能还有各种不同的配置方式,本文就 ...

  6. Confluence 6 企业环境或者网站托管的 Java 配置策略

    Confluence 需要依赖一些 Java 的库才能够允运行.一些依赖的 Java 库应用了 Java 的语言特性,但是又是被 Java 的安全策略所限制的. 这个通常来说是不会造成任何问题的.默认 ...

  7. Linux防火墙简介 – iptables配置策略

    Linux防火墙简介 – iptables配置策略 Netfilter/iptables简介 要想真正掌握Linux防火墙体系,首先要搞清楚Netfilter和iptables的关系,Netfilte ...

  8. Microsoft EDP(enterprise database protection)配置策略中的三种Rule template

    搭建Microsoft EDP环境: Microsoft 10 insider preview,Microsoft Intune,ie10(要安装插件silverlight) 这里暂时只说在进行配置策 ...

  9. Maven项目打包时指定配置策略

    以数据库连接池的配置文件(db.properties)为例,一般的项目会有开发用数据库,测试用数据库,正式环境数据库三种配置. 以前的做法是拷贝成三份,注释掉其他了两份 # 开发用 jdbc.url ...

随机推荐

  1. 搞清楚 Python 的迭代器、可迭代对象、生成器

    很多伙伴对 Python 的迭代器.可迭代对象.生成器这几个概念有点搞不清楚,我来说说我的理解,希望对需要的朋友有所帮助. 1 迭代器协议 迭代器协议是核心,搞懂了这个,上面的几个概念也就很好理解了. ...

  2. 使用Typescript重构axios(十七)——增加axios.create接口

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  3. dp的林林总总(持续更新,dp骚气解法等等)

    写在前面: 本人dp较弱,所以总结了一些坑点,转化思路以供复习使用,勿喷,甚至一些不是dp的题(贪心等等)也会放在这. 每个点后面会有我自己的题解,如果没有链接,向下找第一个链接,可能会有多题. 1. ...

  4. Xshell和Xftp 安装及使用

    Xshell Xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议.Xshell 通过互联网到远程主机的安全连接以 ...

  5. Css3动画-@keyframes与animation

    一.@keyframe 定义和用法 @keyframes是用来创建帧动画的,我们通过这个属性可以用纯css来实现一些动画效果. 一般格式是: @keyframes 动画名称{ 0%{ 动画开始时的样式 ...

  6. springboot封装JsonUtil,CookieUtil工具类

    springboot封装JsonUtil,CookieUtil工具类 yls 2019-9-23 JsonUtil public class JsonUtil { private static Obj ...

  7. 手把手教你用netty撸一个ZkClient

    原文地址: https://juejin.im/post/5dd296c0e51d4508182449a6 前言 有这个想法的缘由是前一阵子突发奇想, 想尝试能不能直接利用js连接到zookeeper ...

  8. java编程思想第四版第三章要点习题

    使用"简短的" 和正常的 打印语句来编写一个程序 package net.mindview.util; public class Print { /** * 不带有回车 * @pa ...

  9. nyoj 115-城市平乱 (BFS)

    115-城市平乱 内存限制:64MB 时间限制:1000ms 特判: No 通过数:5 提交数:8 难度:4 题目描述: 南将军统领着N个部队,这N个部队分别驻扎在N个不同的城市. 他在用这N个部队维 ...

  10. 领扣(LeetCode)找树左下角的值 个人题解

    给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2 / \ 1 3 输出: 1 示例 2: 输入: 1 / \ 2 3 / / \ 4 5 6 / 7 输出: 7 注意: 您可以假 ...