ActiveMQ之基本投递模式,消费模式,持久化,死信策略

本文针对近期使用activemq,涉及基本概念及原理,总结如下。个人版本5.X

1.两种模式

queue、topic

2.投递模式

生产者将消息发送到broker

2.1同步投递

方法:send(msg)

特点:发送一条,阻塞等待broker返回ack信息,再发下一条。消息可靠但性能不高。

2.2异步投递(回调)

方法:send(msg,AsyncCallback())

特点:不会阻塞。性能高但消息可能丢失。

配置: 1.ConnectionFactory级别、Connection级别、消息者级别三种
            2.参数dispatchAsync、useAsyncSend设为true

默认情况:非持久消息、事务内消息采用异步投递;未使用事务的持久化消息、明确指定同步方式下采用同步投递。

3.消费端获取消息方式

3.1同步:.receive()方法

3.2异步:实现MessageListener接口,监听消息

4.消费模式

4.1、push(默认)

4.2、pull

  • activeMQ中根据prefetch limit参数来决定(consumer中prefetchSize)
  • 当 prefetchSize = 0 时,pull;当 prefetchSize > 0 时,push
  • prefetchSize参数默认为1000即push

4.3、预取机制prefetchSize

4.3.1同步方式下:prefetch limit可设为0,也可大于0

  • =0时pull:receive()方法首先发送一个pull命令并阻塞,直到broker返回,也就是只能消费者逐个获取消息
  • >0时push:broker端批量push到client一定数量(<=prefetchSize)消息,client端将消息放到本地队列,只要此队列有消息,receive()方法立即返回,当一定量的消息ACK后,broker端继续批量push

4.3.2异步方式:只能>0

只能大于0,用push,因为异步方式下消费者被动获取消息不会主动去轮询消息,而=0意味着不会主动push消息给消费者,二者矛盾。

5.消费端参数

  • taskExecutor:任务调度器,使用线程池并发消费。
  • concurrentConsumers:消费者最大个数(并行消费,默认值1)
  1. spring中messageListener实例是单例的,所以spring-jms不能自作主张的创建多个messageListener实例来并发消费,
  2. 所以spring在内部,创建了多个MessageConsumer实例,并使用consumer.receive()方法以阻塞的方式来获取消息,当获取消息后,在执行messageListener.onMessage()方法
  3. concurrentConsumers属性就是为了指定spring内部可以创建MessageConsumer的最大个数
  4. 若右consumer空闲则会“idle”并从consumer列表移除,若都是“actice”,则会创建新的consumer实例直到maxConcurrentConsumers
  • optimizeAcknowledge:优化ACK批量确认
  1. 可在connectionFactory中配置
  2. 对consumer而言,该属性只在自动ack下生效
  3. 结合prefetchSize参数,协同作用,优化消费端起到批量获取消息、批量延迟确认。

6.持久化

6.1默认

queue默认是持久化,topic默认非持久化

6.2方式

AMQ/KahaDB(默认)/LevelDB/JDBC

6.3逻辑

        发送者将消息发送到MQ服务器后,消息中心首先将消息持久化到本地数据文件、内存数据库或者远程库等,在试图将消息发送给接收者,成功则将消息从存储中删除,失败则继续尝试发送。

6.4目录

db.1.log:数据被追加到db-编号.logs中,当不在需要log文件中的数据时,log文件会被丢弃。

db.data:索引(B-tree)文件,指向db.number.log中每一条消息

db.redo:用来进行消息恢复,恢复BTree索引

6.5KahaDB消息存储器结构

  1. Data logs:存储每一条持久化的消息内容,尾部追加方式,默认32M一个文件(预占),文件中全部消息都被成功消费后,会在Metadata cache中被标记删除,下个周期删除
  2. Metadata Cache:为更快查找某个具体消息在Data logs中的位置,消息的位置索引B-tree结构被存储在内存中,如果消息快速消费了就不用再存到磁盘了
  3. Metadata Store:内存中没被处理的消息索引B-tree会以一定周期或一定数量的方式(可配)同步到store中,以便mq节点重启后Metadata Cache进行恢复

6.6KahaDB配置属性

activemq.xml中KahaDB相关常用参数如下

  • directory:指定持久化消息的存储目录
  • journalMaxFileLength:指定保存消息的日志文件大小(默认32M),具体根据实际应用配置
  • indexWriteBatchSize:Metadata cache区域和Metadata store区域不同的索引数量达到这个值后,Metadata cache将会发起checkpoint同步(默认1000)
  • indexCacheSize:内存中,索引的页大小(默认1000)。超过这个大小Metadata cache将会发起checkpoint同步
  • cleanupInterval:清除(或归档)不再使用的db-*.log文件的时间周期(毫秒)(默认30000)。

bin/env中可配置mq的jvm参数,对应ACTIVEMQ_OPTS_MEMORY属性

7.死信策略

通过配置文件(conf/activemq.xml)来调整死信发送策略

1.共享(默认)

将所有死信放入一个共享队列中,默认名ActiveMQ.DLQ,可设置

2.独立

        放入各自死信队列中,前缀ActiveMQ.DLQ.Queue(queue)、ActiveMQ.DLQ.Topic(topic),默认情况下对于queue和topic,broker都将使用queue保存死信即死信通道通常为Queue,也可指定Topic

  • 删除过期的消息而不发送到死信队列中

新增policyEntry标签节点,"processExpired"表示是否将过期的消息放到死信队列,默认true
注意:对于非过期因素而进入死信队列的数据,上述配置无法删除

  • 死信队列清除

策略1:新增policyEntry标签节点,使用插件plugins节点直接抛弃该队列


策略2:新增policyEntry标签节点,使用定时删除策略,区分queue='>'和topic='>'


注意:修改配置前进入的数据不会清除 

  • 存放非持久的消息到死信队列

        默认持久消息过期会被送到DLQ,非持久消息不会送到DLQ。可通过"processNonPersistent"(默认false)来配置将非持久消息过期到死信。

8.定期清理不活动队列

8.1场景

        一定时间内为空队列。Topic和Queue在不使用之后,可以通过web控制台或是JMX方式来删除掉,也可配置如下

8.2配置

新增policyEntry标签节点,三个参数(周期、开关、检测次数)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值