友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
JMS简明教程(PDF格式)-第8部分
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!
还是被回滚。当非事务性的发送一个 PERSISTENT 消息和发送方法返回之间产生错误时,会
产生同样的不确定性问题。
这种不确定性由JMS 应用来处理。在某些情况下,这可能会造成客户端生产重复消息。
由于恢复被重发的消息不认为是重复消息。
4。4。14 客户端代码的有序执行
尽管java 语言本身提供多线程,但写多线程程序仍然比写单线程程序困难。
因此,JMS 不会引起客户端代码的并非执行,除非客户端显式地要求这样做。做到这一
点的一种途径是一个会话对所有消息的异步转发进行排序。
为了异步接收消息,客户端向MessageConsumer 注册实现了JMS MessageListener 接口
的对象。事实上,会话使用一个单线程来运行所有的MessageListener。当线程正在执行一个
监听器时,所有其他被异步转发的消息必须等待。
4。4。15 并行消息转发
希望并行转发的客户端可以使用多会话。事实上,每个会话的监听器线程并行的运行。
当会话上的监听器正在执行时,在另一个会话上的监听器也可以被执行。
注意,JMS 本省不提供并行处理主题消息集合的功能(这些消息被转发到单个消费者)。
客户端可以使用单个消费者但实现多线程逻辑来并行处理这些消息;但是,这样做是不可靠
的,因为JMS 没有事务功能来处理这种方式需要的并发事务。
4。5 MessageConsumer
客户端使用 MessageConsumer 来接收来自目的地的消息。通过向 Session 的
createConsumer 方法传入Queue 或Topic 来创建MessageConsumer。
消费者可以用消息选择器来创建。这可以让客户端限制转发到消费者的消息,只有符合
39 / 66
…………………………………………………………Page 40……………………………………………………………
选择器的消息才能被转发到该消费者。参见节3。8。1 “消息选择器”了解更详细的信息。
客户端可以同步接收消费者的消息,也可以让提供商在消息到达时异步地转发消息。
4。5。1 同步转发
客户端可以要求来自MessageConsumer 的下一个消息使用某个receiver 方法。有几个接
收变量可以让客户端获取或等待下一个消息。
4。5。2 异步转发
客户端可以向MessageConsumer 注册一个实现了JMS MessageListener 接口的对象。当
消息到达消费者时,提供商通过调用监听器的onMessage 方法来转发它们。
监听器可能会抛出RuntimeException;但是这被看作是客户端程序错误。好的监听器应
当捕获这种异常并尽量将产生异常的消息转发到应用的‘未处理消息’目的地。
监听器抛出RuntimeException 的结果依赖于会话的确认模式。
z AUTO_ACKNOWLEDGE 或DUPS_ACKNOWLEDGE——消息被立即重发。JMS 提供商在
放弃之前重发同一个消息次数由提供商决定。在这种情况下,将为重发的消息设置
JMSRedelivered 消息头字段。
z CLIENT_ACKNOWLEDGE——为监听器转发下一个消息。如果客户端希望让前一个未
确认的消息被重发,那么它必须手工恢复会话。
z 事务性的会话——为监听器转发下一个消息。客户端可以提交或回滚这个会话(换
句话说,RuntimeException 不自动回滚这个会话)。
JMS 提供商应当对抛出RuntimeException 作为可能故障的具有消息监听器的客户端进行
标记。
参见节4。4。14 “客户端代码的顺序执行”了解onMessage 如何被会话有序的调用。
4。6 MessageProducer
客户端使用MessageProducer 来向Destination 发送消息。通过向会话的createProducer
方法传入Queue 或Topic 来创建MessageProducer。
客户端也可以不提供目的地来创建消息生产者。在这种情况下,必须在每次发送操作时
提供目的地。这种风格的生产者的通常用于使用请求的 JMSReplyTo 目的地来发送请求的回
复。
客户端可以指定一个缺省的转发模式、优先级和消息的生存时间。它也可以为每个消息
指定转发模式、优先级和消息的生存时间。
客户端每次创建一个MessageProducer,它定义了一个新的消息序列,这些消息和以前
发送的消息没有顺序关系。
参见节3。4。9 “JMSExpiration ”进一步了解生存时间。参见节3。4。10 “JMSPriority ”进一
步了解优先级。
40 / 66
…………………………………………………………Page 41……………………………………………………………
4。7 消息转发模式
JMS 支持两种消息转发模式。
z NON_PERSISTENT 模式是最小符合的转发模式。因为它不要求将消息记录到稳定存
储器中。JMS 提供商失败可能导致NON_PERSISTENT 消息丢失。
z PERSISTENT 模式告诉JMS 提供商要保证在转发期间消息不能由于JMS 提供商失败
而造成消息丢失。
JMS 提供商必须“最多一次的”转发NON_PERSISTENT 消息。这意味着它可能丢失消息,
但不会转发两次。
JMS 提供商必须“有且只有一次的”转发 PERSISTENT 消息。这意味着JMS 提供商的失
败不能引起消息的丢失,但不会转发两次。
PERSISTENT 和NON_PERSISTENT 消息转发对JMS 客户端来说是两种转发技术的选择,一
种是在JMS 提供商不工作时可以丢失消息,另一种是尽力保证消息在JMS 提供商失败时还
要存在。这种选择暗含了性能/可靠性的平衡。当客户端选择NON_PERSISTENT 转发模式时,
它表示它更看重性能而不是可靠性;选择PERSISTENT 则相反。
使用PERSISTENT 消息不保证所有的消息总是被转发到每个合格的消费者。参见节4。10
“可靠性”做进一步了解。
4。8 消息的生存时间
客户端可以为它发送的每个消息以毫秒为单位指定生存时间。它定义了消息的到期时间,
到期时间是消息的生存时间和发送的GMT 的和(对于事务性发生,这个时间是客户端发送
消息的时间,不是事务提交的时间)。
JMS 提供商应当尽力做到精确的终止消息;但是,JMS 没有定义如何提供精确性。简单
地忽略生存时间是不可接受的。
参见3。4。9 “JMSExpiration ”了解消息到期的更详细信息。
4。9 异常
JMSException 是所有JMS 异常的基类。参见第7 章“JMS 异常”了解更详细的信息。
4。10 可靠性
大多数客户端应当使用生产 PERSISTENT 消息的生产者。这样可以保证有且只有一次的
转发来自队列或永久订阅的消息。
在某些情况下,应用只可以要求最多一次的消息转发。通常在发布NON_PERSISTENT 消
息时使用。这些消息通常有较低的负荷;但是,这些消息可能在JMS 提供商失败时被丢失。
PERSISTENT 和NON_PERSISTENT 消息都能被发布到同一个目的地。
通常,一个消费者在确认之前完整处理每个消息。这保证 JMS 不会因为机器出问题等
而导致丢弃部分处理的消息。消费者通过使用事务的或CLIENT_ACKNOWLEDGE 会话来达到。
JMS 提供商必须设置由于系统失败而导致重发的未确认的消息的JMSRedelivered 消息头字段。
41 / 66
…………………………………………………………Page 42……………………………………………………………
如果NON_PERSISTENT 消息被转发到永久订阅或一个队列,那么如果永久订阅变成不活
动的(也就是,如果它当前没有订阅者)或 JMS 提供商关闭然后被重新启动,则转发不受
保证。
重要的消息期望使用 PERSISTENT 转发模式在事务内生产,并且在来自非临时队列或永
久订阅的事务内被消费。
当这些都被做时,应用就拥有了最高级别的保证:消息已经被正确的生产,可靠的转发
和精确的消费。非事务的生产和消费也可以达到相同的保障级别;但是这要求认真的编码。
JMS 提供商可以限制高容量目的地能处理的消息数量或不响应的客户端数量。如果消息
由于消息限制被丢弃,则这是一个需要注意的严重的管理问题。JMS 要求的正确功能是客户
端是响应的且有足够的资源服务于这些客户端。
正如本规范描述的一样,有且只有一次的的消息转发有重要的一点,就是它不会覆盖由
于消息到期或其他管理原因毁坏的消息。它也不覆盖由于资源限制丢失的消息。为 JMS 应
用配置足够的资源和处理能力是管理员的工作,他必须知道JMS 提供商的可靠性特性。
NON_PERSISTENT 消息,非永久性订阅,和临时目的地都是不可靠的。JMS 提供商关闭
或失败时很可能造成NON_PERSISTENT 消息的丢失和临时目的地以及非永久性订阅持有的消
息的丢失。终止应用很可能造成由非永久性订阅和临时目的地持有的消息的丢失。
4。11 方法跨消息域继承
由于统一了消息域,因此某些不适用于一个域的方法可以在域类中被继承。例如,Session
接口有方法createQueueBrowser 。由于TopicSession 继承了Session 接口,因此TopicSession
继承了 createQueueBrowser 方法,尽管这个方法不能被主题使用,也就是主题不支持
QueueBrowser 。表4�1 列出了这些实例。
如果应用企图调用列出的方法,则JMS 提供商必须抛出IllegalStateException。
表4�1 必须抛出IllegalStateException 的方法
接口 方法
QueueConnection createDurableConnectionConsumer
QueueSession createDurableSubscriber
createTemporaryTopic
createTopic
unsubscribe
TopicSession createQueueBrowser
createQueue
createTemporaryQueue
5 JMS 点对点模型
5。1 概述
点对点系统是与消息队列一起工作的。它们是点对点的是因为客户端将消息发送到一个
队列。某些PTP 系统通过给客户端提供自动分发消息功能模糊了PTP 和Pub/Sub 间的差别。
42 / 66
…………………………………………………………Page 43……………………………………………………………
对客户端来讲,通常是将它们的消息转发到单个队列中。
和常见的邮件箱一样,队列可以包含混合消息。但类似于实际的邮件箱,创建和维护每
个队列的成本都是很高的。大多数队列都由管理员创建,并被客户端看作是静态资源。
JMS PTP 模型定义了客户端如何和队列工作;如何找到队列,客户端如何将消息发送给
它们,以及如何从队列中接收消息。
本章描述了PTP 模型的语义。支持PTP 模型的JMS 提供商必须实现这里描述的语义。
不管JMS 客户端程序是否使用PTP 域的接口,还是在第4 章“JMS 公共工具”中描述的
公共接口,客户端程序必须被保证有相同的行为。
表5�1 展示了 PTP 域特有的接口和JMS 的公共接口。公共接口是创建JMS 应用程序的
最佳方式,因为它们是独立于域的。
表5�1 PTP 域接口和JMS 公共接口
PTP 域接口 JMS 最佳的公共接口
QueueConnectionFactory ConnectionFactory
QueueConnection Connection
Queue Destination
QueueSession Session
QueueSender MessageProducer
QueueReceiver MessageConsumer
5。2 队列管理
JMS 没有定义创建、管理或删除长生命队列的工具(没有为TemporaryQueue 提供这样
的机制)。由于大多数客户的使用静态定义的队列,因此这不是问题。
5。3 Queue
Queue 对象封装了提供商特有的队列名称。这个名称是客户端为 JMS 方法指定队列标
识的途径。
JMS 没有定义消息被队列持有的真正时间长度和资源溢出的后果。
参见节4。2 “受管理的对象”了解关于JMS Destination 对象的更多信息。
5。4 TemporaryQueue
TemporaryQueue 是唯一的Queue 对象,它为Connection 或QueueConnection 的永久性
而创建。它是系统定义的队列,只能被创建它的Connection 或QueueConnection 来消费。
参见节4。4。3 “创建临时目的地”了解更详细的信息。
5。5 QueueConnectionFactory
客户端使用QueueConnectionFactory 来创建具有JMS PTP 提供商的QueueConnection 。
参见节4。2 “受管理对象”了解关于JMS QueueConnectionFactory 对象更多的信息。
43 / 66
…………………………………………………………Page 44……………………………………………………………
5。6 QueueConnection
QueueConnection 是一个对JMS PTP 提供商的活动连接。客户端使用QueueConnection
来创建一到多个用于生产和消费消息的QueueSession 。
参见节4。3 “Connection ”了解更详细的信息。
5。7 QueueSession
QueueSession 提供了创建 QueueReceiver 、 QueueSender 、 QueueBrowser 和
TemporaryQueue 的方法。
如果在 QueueSession 终止时还有已被接收但还没被确认的消息,那么这些消息必须被
保留,且在消费者下一次访问队列时被重发。
参见节4。4 “Session ”了解更详细的信息。
5。8 QueueReceiver
客户端使用QueueReceiver 来接收已被转发到队列的消息。
尽管里两个会话可以有连接到同一个队列的 QueueReceiver ,但 JMS 没有定义在
QueueReceiver 间如何分发消息。
如果QueueReceiver 指定了消息选择器,那么没被选中的消息仍然在队列中。根据定义,
消息选择器可以让QueueReceiver 跳过消息。这意味着当跳过的消息最终被读时,总的读排
序不保留由每个消息生产者定义的部分排序。只有没有消息选择器的QueueReceiver 才按照
消息生产者指定的顺序读消息。
参见4。5 “MessageConsumer”了解更详细的信息。如果MessageConsumer 正在从Queue
中消费消息,那么它的行为必须和节5。8 “QueueReceiver”中描述的一样。
客户端使用MessageProducer 或QueueSender 来向Queue 发送消息。
参见节4。6 “MessageProducer”了解更详细的信息。
5。9 QueueBrowser
客户端使用QueueBrowser 来查看队列中的消息,但不删除它们。QueueBrowser 可以从
Session 或QueueSession 来创建。
浏览方法返回java。util。Enumeration ,它用于遍历队列中的消息。它可以是队列的全部内
容,或它只包含批评消息选择器的消息。
当在浏览消息时,消息可以到达和到期。JMS 不要求枚举的内容是对列内容的静态快照。
这些变化是否可见依赖于JMS 提供商。
5。10 QueueRequestor
JMS 提供了一个QueueRequestor 帮助类来简化服务请求。
QueueRequestor 构造器需要一个 QueueSession 和目的地队列。它为响应创建
44 / 66
…………………………………………………………Page 45……………………………………………………………
TemporaryQueue ,并提供了一个request 方法来发送请求信息和等待回复。
5。11 可靠性
队列通常由管理员创建,并长时间存在。它总是持有发送到它的消息,不管消费消息的
客户端是否是活动的。因此,客户端不必担心它会错过消息。
6 JMS 发布/订阅模型
6。1 概述
JMS Pub/Sub 模型定义了JMS 客户端如何发布消息到基于内容层次的众所周知的节点和
如何从节点订阅消息。JMS 将这些节点称为主题(topic )。
在这一节,术语publish 和subscribe 用于替代前面更常用的术语produce 和consume 。
注意可以被看作是一个小的消息代理,它收集和分发定位到它的消息。通过依靠主题作
为中介,消息发布者和订阅者保持独立。主题随着发布者和订阅者的变化而自动适配。
当代表它们的Java 对象存在时,发布者和订阅者是活动的。JMS 也支持可选的永久订
阅者,这些订阅者在不活动时也会被记住是存在的。
本章描述 Pub/Sub 模型的语义。支持 Pub/Sub 模型的JMS 提供商必须支持这里描述的
语义。
不管JMS 客户端程序使用Pub/Sub 域特有的接口还是使用在第4 章“JMS 公共工具”中
描述的公共接口,客户端程序必须被保证有相同的行为。
表6�1 展示了Pub/Sub 域特有的接口和JMS 的公共接口。公共接口是创建JMS 应用程序
的最佳方式,因为它们是独立于域的。
表6�1 Pub/Sub 域接口和JMS 公共接口
Pub/Sub 域接口 JMS 最佳的公共接口
TopicConnectionFactory ConnectionFactory
TopicConnection Connection
Topic Destination
TopicSession Session
TopicPublisher MessageProducer
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!