消息确认机制

  消息确认协议是保证消息传送的关键所在,同时,支持确认也是 JMS API 语义的要求。以下将分别从消息生产者、消息服务器、消息消费者的角度,来考察消息确认机制。

从消息生产者的角度考察

  在表象之下,TopicPublisher.publish() 或 QueueSender.send() 方法是同步的。这些方法负责发送消息,同时进行阻塞,直到从消息服务器接收到一个确认为止。一旦接收到一个确认,执行线程就会恢复并返回方法,并像正常情况那样继续处理。底层确认对客户端编程模型来说是不可见的。如果在这个操作期间发生了一个故障情况,就会抛出一个异常,同时认为该消息未被传送。

从消息服务器的角度考察

  从消息服务器的发送到生产者,意味着服务器已经接收到该消息,并已经承担了传送它的责任。

  在发布/订阅模型中,消息服务器向每个订阅者都传送了消息的一个副本。对于持久订阅者来说,一直到消息服务器接收到所有的消息预定接收者的确认时,消息服务器才会认为该消息已经完成传送。一旦消息服务器将消息传送给所有的已知订阅者,并已分别从这些订阅者那里接收到确认,就会将这些消息从持久存储器中删除。

  如果订阅是持久的,而且订阅者当前并未连接,那么,消息服务器就会将该消息保存起来,直到该订阅者变为可用状态或消息到期为止。甚至对于非持久性消息来说,也是如此。如果一条非持久性消息原本打算供未连接的持久订阅者使用,消息服务器会将该消息保存到磁盘中,就好像它是一条持久性消息一样。这时,持久性和非持久性这两种消息的差异虽然很细微,但是非常重要。对于非持久性消息来说,在消息服务器已经向发送者确认消息之后和消息服务器有机会代表未连接的持久订阅者将消息写人磁盘之前,这二者之间可能会有一个时间窗。如果 JMS 提供者在这个时间窗内出现故障,该消息就可能会丢失。不过,JMS 规范虽然暗示了可能会出现这种故障情况。但实际上 JMS 提供者可能不会允许这种情况出现。在使用持久性消息时,一个提供者可能会出现故障,并且优雅地恢复正常。由于消息保存在持久存储器中,它们并没有丢失。在提供者再次启动时,它们又会传送给消费者。

从消息消费者的角度考察

  从消费者的角度考虑,当每个消费者获得消息时,它需要向服务器发送确认信息。如果服务器没有收到这个确认信息,它就会认为该消息未被传送,并可能试图重新传送。
在将一条消息传送给非持久订阅的消费者时,如果提供者出现故障,这条消息就可能会丢失。如果一个持久订阅接收到一条消息,并在向提供者返回确认之前出现了故障,那么,JMS 提供者就会认为该消息未被传送,并试图对它进行重新传送。在这种情况下,“一次而且是仅仅一次”的要求就值得怀疑。消费者可能会再次接收到该消息,重新传送的消息会被设置 JMSRedelived 标记。为了预防消息重复,应用程序可以检查重新传送的消息是否已被处理。

消费者确认消息的方式

AUTO_ACKNOWLEDGE

  当消费者获取消息时,JMS 提供者的客户端运行时环境必须自动向服务器发送确认信息。

DUPS_OK_ACKNOWLEDGE

  AUTO_ACKNOWLEDGE 模式允许消费者在收到多个消息之后一次完成确认。

CLIENT_ACKNOWLEDGE

  CLIENT_ACKNOWLEDGE 模式中,接收消息的客户端可以通过 javax.jms.Message.acknowledge() 方法控制何时发送确认。

public void onMessage(Message message) {
try {
// 获取消息来执行相关的业务逻辑
... message.acknowledge(); // 执行更多的 业务逻辑
...
} catch (Exception e) {
// 捕获抛出的异常,并取消局部处理结果
...
}
}

JMS - 消息确认的更多相关文章

  1. JMS开发(三):JMS消息的确认方式

    这里单独列出来我也是觉得有点必要的,毕竟JMS总体知识点并不多,这点可能被很多人所忽视. 首选定义:消息的确认是指消息接受者接到消息,并做出了对应的处理之后,它将回送一个确认消息. 对于非事务性会话, ...

  2. 学习ActiveMQ(六):JMS消息的确认与重发机制

    当我们发送消息的时候,会出现发送失败的情况,此时我们需要用到activemq为我们提供了消息重发机制,进行消息的重新发送.那么我们怎么知道消息有没有发送失败呢?activemq还有消息确认机制,消费者 ...

  3. ActiveMQ的消息确认问题

    http://riddickbryant.iteye.com/blog/441890 [发送端] session = connection.createSession(Boolean.FALSE,   ...

  4. JMS消息传输机制

    JMS消息传送模型: 消息传送机制, 是基于拉取(pull)或者轮询(polling)的方式.  JMS具备两种"消息传送模型": P2P和Pub/sub. (1) P2P:点对点 ...

  5. JavaEE(6) - JMS消息选择和查看

    1. JMS消息的类型.消息头和消息属性 消息类型: StreamMessage MapMessage TextMessage ObjectMessage BytesMessage JMS消息中的消息 ...

  6. activemq的消息确认机制ACK

    一.简介 消息消费者有没有接收到消息,需要有一种机制让消息提供者知道,这个机制就是消息确认机制. ACK(Acknowledgement)即确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符 ...

  7. 学习ActiveMQ(七):JMS消息的事务管理

    Spring提供了一个JmsTransactionManager用于对JMS ConnectionFactory做事务管理.这将允许JMS应用利用Spring的事务管理特性.JmsTransactio ...

  8. SpringBoot集成RabbitMQ消息队列搭建与ACK消息确认入门

    1.RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.Rabbi ...

  9. JAVA消息确认机制之ACK模式

    JMS API中约定了Client端可以使用四种ACK模式,在javax.jms.Session接口中: AUTO_ACKNOWLEDGE = 1    自动确认 CLIENT_ACKNOWLEDGE ...

随机推荐

  1. UVA 11426 GCD - Extreme (II) (欧拉函数+筛法)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=70017#problem/O 题意是给你n,求所有gcd(i , j)的和,其中 ...

  2. 使用gcc编译gdb调试

    gcc 在linux系统中,默认是没有安装gcc编译器的,可以通过命令 rpm -q | grep gcc 来查看.安装命令为: yum -y install gcc 安装后,编写一个.c结尾的文件. ...

  3. HR(人事管理)

    HRMS(Human Resource Management System) --人员 per_people_f --人员分配 per_all_assignments_f --要素 DECLARE l ...

  4. VS里面如何设置环境默认的开发语言

  5. Codeforces Testing Round #12 C. Subsequences 树状数组维护DP

    C. Subsequences Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/597/probl ...

  6. HDU 4593 H - Robot 水题

    H - RobotTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.act ...

  7. [置顶] SNMP协议详解<二>

    上一篇文章讲解了SNMP的基本架构,本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1.v2c.v3)进行区别! 四.SNMP协议数据单元 在SNMP管理中,管理站(NMS)和代理(Agent ...

  8. 经常使用的android弹出对话框

    我们在平时做开发的时候,免不了会用到各种各样的对话框,相信有过其它平台开发经验的朋友都会知道,大部分的平台都仅仅提供了几个最简单的实现,假设我们想实现自己特定需求的对话框,大家可能首先会想到,通过继承 ...

  9. 使用自定义的BaseAdapter实现LIstView的展示

    http://stephen830.iteye.com/blog/1141394 使用自定义的BaseAdapter实现LIstView的展示 实现以下功能点: 1.通过自定义的BaseAdapter ...

  10. 利用ajax获取到的网页源码不能执行js代码

    今天觉得我的博客中加载腾讯微博的速度很慢,所以就想改写为js,本来以为直接新建一个页面,把获取函数移到新的页面中,原来的页面只要使用xmlhttp去GET一下,然后把div的innerhtml属性等于 ...