ActiveMQ基础08:producerAPI(消息有效性、消息优先级)

目录

一、消息有效性

二、消息优先级

2.1 配置开启顺序

2.2 强顺序

2.3 严格顺序


一、消息有效性

消息过期后,默认会将失效消息保存到“死信队列(ActiveMQ.DLQ)”

不持久化的信息,在超时后直接丢弃,不会报错到死信队列中。

死信队列名称可配置,死信队列中的消息不能恢复

可在activemq.xml文件中配置

上一篇有原码:

第一个参数,消息正文

第二个参数:持久化模式

 DeliveryMode.PERSISTENT - 持久化,消息会持久化到数据库(kahadb,JDBC等)

DeliveryMode.NON_PERSISTENT - 非持久化,消息只保存到内存

第三个参数:优先级

取值范围【0~9】,取值越大优先级越高。不能保证绝对顺序

必须在activemq.xml配置文件的borker标签中增加配置

第四个参数:消息有效期

单位毫秒,有效期超时,消息自动放弃

producer代码段中main方法(消息发送,10s失效)

producer.sendMessageWithParameters("send message for parameters", DeliveryMode.PERSISTENT, 0, 1000*10);

JDBC持久化,死信队列数据

二、消息优先级

我们可以在发送消息时,指定消息的权重,broker 可以建议权重较高的消息将会优先发送给 Consumer。在某些场景下,我们通常希望权重较高的消息优先传送;不过因为各种原因,priority 并不能决定消息传送的严格顺序 (order)。
JMS 标准中约定 priority 可以为 0~9 的整数数值,值越大表示权重越高,默认值为 4。不过 activeMQ 中各个存储器对 priority 的支持并非完全一样。比如 JDBC 存储器可以支持0~9,因为 JDBC 存储器可以基于 priority 对消息进行排序和索引化;但是对于 kahadb/levelDB等这种基于日志文件的存储器而言,priority 支持相对较弱,只能识别三种优先级(LOW: <4,NORMAL: =4,HIGH: > 4)。

2.1 配置开启顺序

在 broker 端,默认是不存储 priority 信息的,我们需要手动开启,修改 activemq.xml 配置文件,在 broker 标签的子标签 policyEntries 中增加下述配置:

<policyEntry queue=">" prioritizedMessages="true"/>

不过对于“非持久化”类型的消息(如果没有被 swap 到临时文件),它们被保存在内存中,它们不存在从文件 Paged in 到内存的过程,因为可以保证优先级较高的消息,总是在 prefetch的时候被优先获取,这也是“非持久化”消息可以担保消息发送顺序的优点。
Broker 在收到 Producer 的消息之后,将会把消息 cache 到内存,如果消息需要持久化,那么同时也会把消息写入文件;如果通道中 Consumer 的消费速度足够快(即积压的消息很少,尚未超过内存限制,我们通过上文能够知道,每个通道都可以有一定的内存用来 cache消息),那么消息几乎不需要从存储文件中 Paged In,直接就能从内存的 cache 中获取即可,这种情况下,priority 可以担保“全局顺序”;不过,如果消费者滞后太多,cache 已满,就会触发新接收的消息直接保存在磁盘中,那么此时,priority 就没有那么有效了。在 Queue 中,prefetch 的消息列表默认将会采用“轮询”的方式(roundRobin,注意并不是roundRobinDispatch)[备注:因为Queue不支持任何DispatchPolicy],依次添加到每个consumer的 pending buffer 中,比如有 m1-m2-m3-m4 四条消息,有 C1-C2 两个消费者,那么:m1->C1,m2->C2,m3->C1,m4->C2。这种轮序方式,会对基于权重的消息发送有些额外的影响,假如四条消息的权重都不同,但是(m1,m3)->C1,事实上 m2 的权重>m3,对于 C1 而言,它似乎丢失了“顺序性”。

2.2 强顺序

<policyEntry queue=">" strictOrderDispatch="true"/>

strictOrderDispatch“严格顺序转发”,这是区别于“轮询”的一种消息转发手段;不过不要误解它为“全局严格顺序”,它只不过是将 prefetch 的消息依次填满每个 consumer 的 pending buffer 。 比 如 上 述 例 子 中 , 如 果 C1-C2 两 个 消 费 者 的 buffer 尺 寸 为 3 , 那 么(m1,m2,m3)->C1,(m4)->C2;当 C1 填充完毕之后,才会填充 C2。由此这种策略可以保证 buffer中所有的消息都是“ 权重临近的 ”、有序的。(需要注意:strictOrderDispatch 并非是解决 priority消息顺序的问题而生,只是在使用 priority 时需要关注它)。

2.3 严格顺序

<policyEntry queue=">" prioritizedMessages="true" useCache="false" expireMessagesPeriod="0" queuePrefetch="1"/>

useCache=false 来关闭内存,强制将所有的消息都立即写入文件(索引化,但是会降低消息的转发效率);queuePrefetch=1 来约束每个 consumer 任何时刻只有一个消息正在处理,那些消息消费之后,将会从文件中重新获取,这大大增加了消息文件操作的次数,不过每次读取肯定都是 priority 最高的消息。

producer代码段中main方法(消息发送,10s失效)

producer.sendMessageWithParameters("2", DeliveryMode.PERSISTENT, 2, 0);
producer.sendMessageWithParameters("9", DeliveryMode.PERSISTENT, 9, 0);
producer.sendMessageWithParameters("7", DeliveryMode.PERSISTENT, 7, 0);
producer.sendMessageWithParameters("5", DeliveryMode.PERSISTENT, 5, 0);

执行顺序

消费顺序

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值