AMQ学习笔记 - 06. 可靠消息传送
概述
故障分析
1.两个跃点
- 发送跃点
Producer将消息发送到JMS Provider的目的地 - 接收跃点
Consumer从JMS Provider的目的地获取消息

2.三个隐患阶段
- 发送阶段
Producer发送消息到目的地,可能会失败。 - 消息缓存阶段
JMS Provider异常导致目的地中缓存的数据丢失。 - 接收阶段
Consumer从目的地接收消息,可能会失败。

可靠传送保障机制
1.Acknowledge - 确认
这个机制可以用于解决发送阶段、接收阶段的安全隐患。
1.1.对于Producer
1.2.对于Consumer
- AUTO_ACKNOWLEDGE
自动确认:会话对收到的每条Message,自动发送接收确认;然后会话线程阻塞,直到收到了JMS Provider发来的处理确认。
接收确认的发送时机:同步接收中,调用receive()方法成功返回;异步接收中,MessageListener的onMessage(Message)方法被调用,并成功返回。 - CLIENT_ACKNOWLEDGE
客户端确认:客户端调用Message#acknowledge()发送接收确认[1];然后会话线程阻塞,直到收到了JMS Provider发来的处理确认。
接收确认的发送时机:显示调用Message#acknowledge()方法。
注:
[1] 每次确认不是只对当前的Message进行确认,而是对自上次确认以来的所有Message进行确认. - DUPS_OK_ACKNOWLEDGE
消息可重复确认:这个机制行为上表现的和AUTO_ACKNOWLEDGE一样,具有延迟确认的特点。这个机制可能会导致收到重复的消息。
接收确认的发送时机:测试中,PTP Mode每一条消息都会即时确认;Pub/Sub Mode在接收的消息数,每超过prefetch size阀值[1]一半的时候确认一次。
注:
[1] 在brokerURL中可以指定参数jms.prefetchPolicy.topicPrefetch作为prefetch size阀值。你可能会猜测:应该也有参数jms.prefetchPolicy.queuePrefetch,可以让DUPS_OK_ACKNOWLEDGE在PTP Mode中也批量确认。但是实验的结果是每一条消息都会即时确认,就好像DUPS_OK_ACKNOWLEDGE只是针对Pub/Sub设定的。
1.3.确认机制的设置
- AUTO_ACKNOWLEDGE - 自动确认
- CLIENT_ACKNOWLEDGE - 客户端确认
- DUPS_OK_ACKNOWLEDGE - 可重复确认
- createSession(boolean transacted, int acknowledgeMode):Session
transacted - 设置事务,后面才会谈到事务,这里设置false就好了
acknowledgeMode - 设置确认机制
1.4.确认机制的获取
- getAcknowledgeMode():int
返回结果有4种,除了上述的3种确认机制之外,还有一个Session.SESSION_TRANSACTED表示Session启用了事务。
1.5.测试
2.Transaction - 事务
| 对比内容\事务 | JDBC事务 | JMS事务 |
| 范围 | java.sql.Connection实例的生命周期之内 | javax.jms.Session实例的生命周期之内 |
| 设置和获取 | java.sql.Connection:
|
javax.jms.Connection:
javax.jms.Session:
|
| 操作 | java.sql.Connection:
|
javax.jms.Session:
|
| 对比内容\机制 | 确认机制 | 事务机制 |
| 本质 | 确保消费者能够获取到消息,在收到消费者的确认之后,才会将消息从目的地移除。 | 将多个操作绑在一起,成为原子操作,从而有相同的操作结果(成功或失败)。 |
| 客户端编程 | 在Producer端是透明的,只能在Consumer端进行控制。 | 可以在Producer和Consumer端实施控制。 |
| 功能性 | 确认消息已收到。 | 事务的commit,提供类似于批量确认的功能。 不要单纯为了批量确认而使用事务,要从业务的需要上考虑使用事务。 |
- 如果第一个参数为true,表示启用事务,第二个参数就会被忽略(建议传入Session.SESSION_TRANSACTED)
- 如果第一个参数为false,表示不启用事务,第二个参数用于设置确认模式,就有效了。
2.1.使用模型
try {
// ...
javax.jms.Connection connection = ...;
javax.jms.Session session = connection.createSession(true, Session.SESSION_TRANSACTED);
// send or receive operates
session.commit(); // commit at lase
} catch(JMSException e) {
session.rollback(); // rollback when exception happens
} finally {
// close resources
}
2.2.测试
3.持久化模式
3.1.持久化设置
- setDeliveryMode(int):void
- 设置此producer实例的默认递送模式 - send(Message message):void
- 以默认的deliveryMode发送消息 - send(Message message, int deliveryMode, int priority, long timeToLive):void
- 以指定的deliveryMode发送消息
- static int NON_PERSISTENT
非持久化模式 - static int PERSISTENT
持久化模式
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); // 非持久化
producer.setDelicertMode(DeliveryMode.PERSISTENT); // 持久化
3.2.测试
参考
- 第 2 章 客户端编程模型
本文的骨架是参考这篇文章整理的 - ActiveMQ讯息传送机制以及ACK机制
这篇文章对ACK的机制讲的比较细,我尝试了optimizeACK + prefetch + AUTO_ACKNOWLEDGE的预取机制,以及DUPS_OK_ACKNOWLEDGE在Pub/Sub模式下的延迟确认机制。 - ActiveMQ持久化
介绍了几种常见的持久化方案。
AMQ学习笔记 - 06. 可靠消息传送的更多相关文章
- 机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记
机器学习实战(Machine Learning in Action)学习笔记————06.k-均值聚类算法(kMeans)学习笔记 关键字:k-均值.kMeans.聚类.非监督学习作者:米仓山下时间: ...
- iOS学习笔记06—Category和Extension
iOS学习笔记06—Category和Extension 一.概述 类别是一种为现有的类添加新方法的方式. 利用Objective-C的动态运行时分配机制,Category提供了一种比继承(inher ...
- AMQ学习笔记 - 04. 消息选择器
概述 消息选择器使用类似于SQL语法,为Consumer指定基于Message属性的筛选条件. 消息选择器 发送的时候,给消息添加一些属性:在接收的时候,根据属性进行过滤. API javax.jms ...
- AMQ学习笔记 - 05. 客户端模板化
概述 客户端编程模型中,大部分的步骤都是相同的.将相同的部分做成模板,将不同的部分预留接口,实现者就只需要针对不同的部分提供实现. 设计 类图 发送方客户端 说明: 基于模板的思想,SendTempl ...
- AMQ学习笔记 - 14. 实践方案:基于ZooKeeper + ActiveMQ + replicatedLevelDB的主从部署
概述 基于ZooKeeper + ActiveMQ + replicatedLevelDB,在Windows平台的主从部署方案. 主从部署可以提供数据备份.容错[1]的功能,但是不能提供负载均衡的功能 ...
- AMQ学习笔记 - 02. JMS客户端编程模型
概述 客户端编程模型,是讲如何使用JMS API实现Java应用程序和JMS Provider的通信. 消息传送模式 消息传送模式又称为消息传送域,JMS API定义了两种模式:PTP和Pub/Sub ...
- JMS学习六(ActiveMQ消息传送模型)
ActiveMQ 支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布 /订阅模型),分别称作:PTP Domain 和Pub/Sub Domain. 一.PTP消息传送模型 ...
- AMQ学习笔记 - 01. 相关背景
概述 介绍中间件.MOM.JMS.ActiveMQ,及相互的关系. 中间件 由于业务的不同.技术的发展.硬件和软件的选择有所差别,导致了异构组件或应用并存的局面.要使这些异构的组件协同工作,一个有效的 ...
- [Golang学习笔记] 06 程序实体3 类型断言和类型转换
类型断言: 语法:<目标类型的值>,<布尔参数> := <表达式>.( 目标类型 ) // 安全类型断言<目标类型的值> := <表达式>. ...
随机推荐
- Eclipse使用jre的原理与配置
近期要配置Eclipse环境,Mark当中的一些方法. 下载Eclipse SDK之后我们就要关联JRE,由于Eclipse启动须要JRE. Eclipse启动时寻找JRE的顺序: 1.假设eclip ...
- 深入NGINX:我们如何设计它的性能和扩展性
为了更好地理解设计,你需要了解NGINX是如何工作的.NGINX之所以能在性能上如此优越,是由于其背后的设计.许多web服务器和应用服务器使用简单的线程的(threaded).或基于流程的 (proc ...
- 微信公共服务平台开发(.Net 的实现)7-------发送图文消息
之前我们讲过让微信发送给我们普通的文本信息,下面我们来看看如何发送图文信息,需要注意的是这里说的是,让微信发给我们,而不是我们拍个图片发给微信处理,我们上传图片在以后的章节介绍.下面是发送图文消息的函 ...
- 安卓 SQLite数据库操作实例
前段时间写了个安卓平台下SQLite数据库操作的实例 ,一直没得时间总结 ,今天把它弄出来了. 在Android 运行时环境包含了完整的 SQLite. 首先介绍一下SQLite这个数据库: SQLi ...
- mysqldump 使用 --set-gtid-purged
1.导出时指定字符集,报错Character set 'utf-8' is not a compiled character set and is not specifie .--default-ch ...
- 基于css3的文字3D翻转特效
一款基于css3的文字3D翻转特效.这款特效当鼠标经过文字的时候3D翻转显示阴影.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class="compo ...
- python脚本初探---新手如何直接编写一个hello world模块即可执行的.py文件
废话不多说,就讲一下这个背景吧: 事情是这个样子的~ 本着好学的精神,咱就买了本书,学习python结果呢,发现python的教程都是一个样子滴,上来的第一个hello world 都是通过IDLE来 ...
- Java项目经验——程序员成长的关键(转载)
Java就是用来做项目的!Java的主要应用领域就是企业级的项目开发!要想从事企业级的项目开发,你必须掌握如下要点:1.掌握项目开发的基本步骤2.具备极强的面向对象的分析与设计技巧3.掌握用例驱动.以 ...
- 【Android 界面效果35】管理Fragments
http://www.cnblogs.com/mengdd/archive/2013/01/09/2853254.html
- 在ubuntu 部署svn服务器
(1)安装svn sudo apt-get install subversion (2)新建一个仓库 mkdir /svn/test chmod 777 /svn/test sudo svnadmin ...