频道栏目
首页 > 资讯 > 其他综合 > 正文

ActiveMQ消息传送和确认详解

18-05-11        来源:[db:作者]  
收藏   我要投稿

ActiveMQ消息传送机制

Producer客户端使用来发送消息的, Consumer客户端用来消费消息;
它们的协同中心就是ActiveMQ broker,broker也是让producer和consumer调用过程解耦的工具,最终实现了异步RPC/数据交换的功能。
随着ActiveMQ的不断发展,支持了越来越多的特性,也解决开发者在各种场景下使用ActiveMQ的需求。
比如producer支持异步调用;
使用flow control机制让broker协同consumer的消费速率;
consumer端可以使用prefetchACK来最大化消息消费的速率;
提供"重发策略"等来提高消息的安全性等。
一条消息从producer端发出之后,一旦被broker正确保存,那么它将会被consumer消费,然后ACK,broker端才会删除;
不过当消息过期或者存储设备溢出时,也会终结它。

网上一张图:详细说明了这个过程:

 

上面的图里面写的很清晰。

上半部分是producer的流程,下半部分consumer的流程分为两块,同步的consumer.receive和异步的MessageListener。从图中可以看出异步的MessageLister也是一条一条处理的,由delivered队列控制的。

这张图片中简单的描述了:1)producer端如何发送消息 2) consumer端如何消费消息 3) broker端如何调度。
如果用文字来描述图示中的概念,恐怕一言难尽。
图示中,提及到prefetchAck,以及消息同步、异步发送的基本逻辑;这对你了解下文中的ACK机制将有很大的帮助。

ACK模式与类型介绍:

 

Consumer消费消息的风格有2种: 同步/异步.?使用consumer.receive()就是同步,使用messageListener就是异步。

在同一个consumer中,我们不能同时使用这2种风格,比如在使用listener的情况下,当调用receive()方法将会获得一个Exception。

两种风格下,消息确认时机有所不同。

 

同步调用时,在消息从receive方法返回之前,就已经调用了ACK;因此如果Client端没有处理成功,此消息将丢失(可能重发,与ACK模式有关)。
基于异步调用时,消息的确认是在onMessage方法返回之后,如果onMessage方法异常,会导致消息不能被ACK,会触发重发。

ACK模式详解:

AUTO_ACKNOWLEDGE :

自动确认,这就意味着消息的确认时机将有consumer择机确认.
"择机确认"似乎充满了不确定性,这也意味着,开发者必须明确知道"择机确认"的具体时机,否则将有可能导致消息的丢失,或者消息的重复接收.
当我们使用messageListener方式消费消息时,通常建议在onMessage方法中使用try-catch,这样可以在处理消息出错时记录一些信息,
而不是让consumer不断去重发消息;
如果你没有使用try-catch,就有可能会因为异常而导致消息重复接收的问题,需要注意你的onMessage方法中逻辑是否能够兼容对重复消息的判断。

CLIENT_ACKNOWLEDGE :?

客户端手动确认,这就意味着AcitveMQ将不会“自作主张”的为你ACK任何消息,开发者需要自己择机确认。
无论是“同步”/“异步”,ActiveMQ都不会发送STANDARD_ACK_TYPE,直到message.acknowledge()调用。
如果在client端未确认的消息个数达到prefetchSize * 0.5时,会补充发送一个ACK_TYPE为DELIVERED_ACK_TYPE的确认指令,
这会触发broker端可以继续push消息到client端。

DUPS_OK_ACKNOWLEDGE :

"消息可重复"确认,意思是此模式下,可能会出现重复消息,并不是一条消息需要发送多次ACK才行。
它是一种潜在的"AUTO_ACK"确认机制,为批量确认而生,而且具有“延迟”确认的特点。
对于开发者而言,这种模式下的代码结构和AUTO_ACKNOWLEDGE一样,不需要像CLIENT_ACKNOWLEDGE那样调用acknowledge()方法来确认消息。

SESSION_TRANSACTED :

当session使用事务时,就是使用此模式。

在事务开启之后,和session.commit()之前,所有消费的消息,要么全部正常确认,要么全部redelivery。
这种严谨性,通常在基于GROUP(消息分组)或者其他场景下特别适合。

INDIVIDUAL_ACKNOWLEDGE :

很少使用,它的确认时机和CLIENT_ACKNOWLEDGE几乎一样

当消息消费成功之后,需要调用message.acknowledege来确认此消息(单条),
而CLIENT_ACKNOWLEDGE模式先message.acknowledge()方法将导致整个session中所有消息被确认(批量确认)。
相关TAG标签
上一篇:win10配置java环境变量教程,解决javac不是内部或外部命令等问题
下一篇:Redis日志的错误信息解决过程
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站