ActiveMQ的基本概念与设置

本文深入介绍了ActiveMQ消息中间件的核心特性,包括消息持久化机制、多种消息确认方式、事务处理流程、消息重发机制及如何设置并行消费者等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       
       ActiveMQ 是Apache出品,目前最流行的的开源的消息中间件,它完全支持JMS规范,尽管JMS规范出台已经是很久的事情了,但是JMS在当今的J2EE应用中间仍然扮演着重要的地位。本文对ActiveMQ的基本概念和基本设置做一些介绍。


 一.ActiveMQ消息持久化

       同时满足以下条件时消息将被持久化到硬盘。

       1.在broker中设置属性persistent=”true”(默认是true);

       2.发送的消息也应该是persitent类型的,这是 ActiveMQ 的默认传送模式,此模式保证这些消息只被传送一次和成功使用一次。

       ActiveMQ消息持久化有三种方式:AMQ、KahaDB(默认)、JDBC。如果要发送非持久化(NON_PERSISTENT)消息,可在配置JmsTemplate时设置<property name="deliveryMode" value="1" /> <!-- 发送模式  DeliveryMode.NON_PERSISTENT=1:非持久 ; DeliveryMode.PERSISTENT=2:持久-->


二.消息确认机制

       JMS API中约定了Client端可以使用四种ACK_MODE,在javax.jms.Session接口中:

       AUTO_ACKNOWLEDGE = 1    自动确认
       CLIENT_ACKNOWLEDGE = 2    客户端手动确认  
       DUPS_OK_ACKNOWLEDGE = 3    自动批量确认
       SESSION_TRANSACTED = 0    事务提交并确认

       此外AcitveMQ补充了一个自定义的ACK_MODE:
       INDIVIDUAL_ACKNOWLEDGE = 4    单条消息确认

       在开发JMS应用程序的时候,会经常使用到上述ACK_MODE,其中"INDIVIDUAL_ACKNOWLEDGE "只有ActiveMQ支持,当然开发者也可以使用它.。ACK_MODE描述了Consumer与broker确认消息的方式(时机),比如当消息被Consumer接收之后,Consumer将在何时确认消息。对于broker而言,只有接收到ACK指令,才会认为消息被正确的接收或者处理成功了,通过ACK,可以在consumer与Broker之间建立一种简单的“担保”机制。

       Client端指定了ACK_MODE,但是在Client与broker在交换ACK指令的时候,还需要告知ACK_TYPE,ACK_TYPE表示此确认指令的类型,不同的ACK_TYPE将传递着消息的状态,broker可以根据不同的ACK_TYPE对消息进行不同的操作。

       在JMS API中并没有定义ACT_TYPE,因为它通常是一种内部机制,并不会面向开发者。ActiveMQ中定义了如下几种ACK_TYPE(参看MessageAck类):

       DELIVERED_ACK_TYPE = 0    消息"已接收",但尚未处理结束
       STANDARD_ACK_TYPE = 2    "标准"类型,通常表示为消息"处理成功",broker端可以删除消息了
       POSION_ACK_TYPE = 1    消息"错误",通常表示"抛弃"此消息,比如消息重发多次后,都无法正确处理时,消息将会被删除或者DLQ(死信队列)
       REDELIVERED_ACK_TYPE = 3    消息需"重发",比如consumer处理消息时抛出了异常,broker稍后会重新发送此消息
       INDIVIDUAL_ACK_TYPE = 4    表示只确认"单条消息",无论在任何ACK_MODE下   
       UNMATCHED_ACK_TYPE = 5    BROKER间转发消息时,接收端"拒绝"消息

       Client端在不同的ACK_MODE时,将在不同的时机发送ACK指令,每个ACK Command中会包含ACK_TYPE,那么broker端就可以根据ACK_TYPE来决定此消息的后续操作。我们需要在创建Session时指定ACK_MODE,由此可见,ACK_MODE将是session共享的,意味着一个session下所有的 consumer都使用同一种ACK_MODE。

       在"异步"(messageListener)方式中,将会首先调用listener.onMessage(message),此后再ACK。如果onMessage方法异常,将导致client端补充发送一个ACK_TYPE为REDELIVERED_ACK_TYPE确认指令;如果onMessage方法正常,消息将会正常确认(STANDARD_ACK_TYPE)。此外需要注意,消息的重发次数是有限制的,每条消息中都会包含“redeliveryCounter”计数器,用来表示此消息已经被重发的次数,如果重发次数达到阀值,将会导致发送一个ACK_TYPE为POSION_ACK_TYPE确认指令,这就导致broker端认为此消息无法消费,此消息将会被删除或者迁移到"dead letter"通道中。

       因此当我们使用messageListener方式消费消息时,通常建议在onMessage方法中使用try-catch,这样可以在处理消息出错时记录一些信息,而不是让consumer不断去重发消息;如果你没有使用try-catch,就有可能会因为异常而导致消息重复接收的问题,需要注意你的onMessage方法中逻辑是否能够兼容对重复消息的判断。


三.使用事务

       在创建Session时,如果此session为事务类型,用户指定的ACK_MODE将被忽略,而强制使用"SESSION_TRANSACTED"类型;如果session非事务类型时,也将不能将 ACK_MODE设定为"SESSION_TRANSACTED"。当session使用事务时,在事务开启之后,session.commit()之前,所有消费的消息,要么全部正常确认,要么全部redelivery。这种严谨性,通常在基于GROUP(消息分组)或者其他场景下特别适合。因为Session非线程安全,那么当前session下所有的consumer都会共享同一个transactionContext;同时建议,一个事务类型的Session中只有一个Consumer,已避免rollback()或者commit()方法被多个consumer调用而造成的消息混乱。 


四.消息重发机制

       在所有的客户端机器上,内存中都运行着一套客户端的ActiveMQ环境,该环境负责缓存发来的消息,负责维持着和ActiveMQ服务器的消息通讯,负责失效转移(fail-over)等,所有的判断和处理都是由这套客户端环境来完成的。Message头里有两个相关字段:Redelivered默认为false,redeliveryCounter默认为0。消息先由broker发送给consumer,consumer调用listener,如果处理失败,本地redeliveryCounter++,给broker一个特定应答,broker即会在内存将消息的redelivered设置为true,redeliveryCounter++,延迟一点时间继续调用,默认1s(配置参数 initialRedeliveryDelay :第一次重发的拖延时间基础,默认是1000毫秒;redeliveryDelay :如果initialRedeliveryDelay 为0,则使用redeliveryDelay ,默认也是1000毫秒)。超过6次(配置参数 maximumRedeliveries :最大重发次数,默认值是6,如果你想不限次数重发,可以设置成-1),则给broker另一个特定应答,broker就直接发送消息到DLQ。但是这两个字段都没有持久化,所以broker重启时这两个字段会被重置为默认值。


五.设置多个并行的消费者

       为了最大效率的完成对消息队列中的消息的消费,一般可以同时起多个一模一样的消费者,以并行的方式来拉取消息队列中的消息。这样的好处有多个:

       1.加快处理消息队列中的消息。

       2.增强稳定性,如果一个消费者出现问题,不会影响对消息队列中消息的处理。

       使用Spring MS来配置多个Listener实例相当简单,只需要配置下MessageListenerContainer就行。多配置一个属性concurrentConsumers,设置值为4,就是同时启动4个Listener实例来消费消息。除了设置一个固定的Listener数量,也可以设置一个Listener区间,这样MessageListenerContainer可以根据消息队列中的消息规模自动调整并行数量。这次使用的是concurrency属性,4-8表示最小并发数是4,最大并发数为8,当然也可以给一个固定值,比如5,这样设置与concurrentConsumers属性效果一样。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值