友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!
第三电子书 返回本书目录 加入书签 我的书架 我的书签 TXT全本下载 『收藏到我的浏览器』

JMS简明教程(PDF格式)-第10部分

快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部! 如果本书没有阅读完,想下次继续接着阅读,可使用上方 "收藏到我的浏览器" 功能 和 "加入书签" 功能!


制线程控制。此时,客户端的控制线程不能进一步配置这个会话。  

   对大多数客户端来说,将它们的工作分派到多个会话是很正常的。这个模型可以让客户 

端简单的启动和随着并发增长的需要而逐渐地增加消息处理。  



                                                             36 / 66  

  


…………………………………………………………Page 37……………………………………………………………

                                     



4。4。7 事务  



    Session 可选地可以被指定为事务性的。每个事务性的会话支持单序列的事务。每个事 

务将一系列生成的消息和一系列消费的消息分组到一个原子工作单元。效果是,事务将会话 

的输入消息流和输出消息流组织称一系列的原子单元。当事务提交时,输入原子单元被确认, 

输出原子单元被发送。如果事务回滚,则它生产的消息被销毁,它消费的消息被自动恢复。 

关于会话恢复的详细信息,参见节4。4。11  “消息确认”。  

    会话使用它的mit()或rollback()方法来完成会话。当前事务完成时会自动启动下一个 

事务。因此,事务性的会话当前总会有一个事务。  

   JTS 或一些其他的事务监控器工具可以被用于将会话的事务和其它资源(数据库,其他 

的JMS 会话等等)上的事务组合在一起。由于Java 分布式事务由JTA 事务分割API 控制,因 

此在这种上下文中使用会话的 mit                    和 rollback 方法将抛出 JMS        的 

TransactionInProgressException 。  



4。4。8 分布式事务  



   JMS 不要求提供商支持分布式事务;但是如果提供商支持了,则应当通过JTA XAResource  

API 来提供分布式事务。  

   JMS 提供商也可以是分布式事务监听器。如果它是,那么它应当通过JTA API 提供事务 

控制。  

    尽管对JMS 客户端来说它可以直接处理分布式事务,但JMS 客户端尽量不要这样做。 

使用基于XA 接口的JMS 客户端在第8 章“JMS 应用服务器工具”中描述,但这种客户端不 

能跨不同的JMS  实现进行移植,因为这些接口是可选的。在JMS  中支持JTA  是为了系统提 

供商能够将JMS 集成到他们的应用服务器产品中。参见第8 章“JMS 应用服务器工具”了解 

更详细的信息。  



4。4。9 多会话  



    一个客户端可以创建多个会话。每个会话都是一个独立的消息生产者和消费者。  

    对于Pub/Sub,如果两个回合都有一个TopicSubscriber ,且都订阅同一个Topic ,那么每 

个订阅者都会收到消息。它们之间不会相互阻塞。  

    对于PTP,JMS 没有指定对同一个Queue 并发QueueReceiver 的语义。但是,JMS 没有 

禁止提供商提供这个功能。因此,向多个QueueReceiver 转发消息将依赖JMS 提供商的实现。 

但这是不可移植的。  



4。4。10 消息排序  



   JMS 客户端不需要理解它们什么时候可以依靠消息排序,什么时候不能。  



                                                                 37 / 66  

  


…………………………………………………………Page 38……………………………………………………………

                                   



4。4。10。1  消息接收的顺序  



    由会话消费的消息定义了一系列的顺序。这个顺序是重要的,因为它定义了消息确认的 

顺序。参见4。4。11  “消息确认”了解详细信息。每个会话消费者交叉读取会话输入消息流中 

的消息。  

   JMS 定义了由会话发送到目的地的消息必须按它们发送的顺序被接收(参见节4。4。10。2 

 “消息发送的顺序”了解限制条件)。这节定义了一部分在会话输入消息流上排序的约束。  

   JMS 没有定义跨目的地接收消息的顺序或从多个会话发送的跨目的地的消息的顺序。会 

话输入消息流的顺序依赖于时间。不在应用的控制之下。  



4。4。10。2  消息发送的顺序  



   尽管客户端松散地查看在会话中生产的消息,这些消息形成了一个有序的发送消息流, 

对流进行整体排序是没有意义的。对接收客户端唯一可见的排序是会话发送到一个特定目的 

地的消息的顺序。有几个事情可以影响整个顺序:  

   z   高优先级的消息可以跳到低优先级消息的前面。  

   z   客户端可以不接收NON_PERSISTENT 的消息,因为JMS 提供商失败造成。  

   z   如果 PERSISTENT 和 NON_PERSISTENT 消息被发送到一个目的地,那么只在转发模 

       式中保证顺序。也就是说,稍晚的NON_PERSISTENT 消息可以在稍早的PERSISTENT 

       之间到达;但是不会在稍早的同优先级的NON_PERSISTENT 消息之前到达。  

   z   客户端使用事务性的会话将会话发送的消息分组到原子单元(一个 JMS  事务的生 

       产者组件)。发送到特定目的地的消息的事务顺序是有意义的。跨目的地发送的消 

       息的顺序是没有意义的。参见4。4。7  “事务”了解更详细的信息。  



4。4。11 消息确认  



   如果会话是事务性的,那么消息确认自动由mit 处理,且恢复自动由rollback 处理。  

   如果会话不是事务性的,有三个确认选择,且手工处理恢复:  

   z   DUPS_OK_ACKNOWLEDGE——这个选项告诉会话懒惰确认消息的传递。如果 JMS 

       失败,这很可能造成传递重复消息,因此这个选项只用于可以忍受重复消息的消费 

       者。它的好处是减少了会话为防止重复所要做的工作。  

   z   AUTO_ ACKNOWLEDGE——使用这个选项,当消息被成功地从调用接收返回或处理 

       消息的MessageListener 成功返回时,会话自动确认客户端的消息接收。  

   z   CLIENT_ ACKNOWLEDGE——使用这个选项,客户端通过调用消息的acknowledge 方 

       法来确认消息。确认一个被消费的消息会自动确认被该会话转发的所有消息。  

   当使用CLIENT_ ACKNOWLEDGE 模式时,客户端可以在处理它们时产生大量未确认消息。 

JMS 提供商应当为管理员提供限制客户端超量运行的途径,以便客户端不会造成资源耗尽并 

保证当它们使用的资源被临时阻塞时造成失败。  

   会话的recover 方法用于停止一个会话然后使用第一个未确认消息来重新启动它。事实 

上,会话的被转发消息序列被重新设置到最后一个确认消息之后。现在转发的消息序列可以 

与起初转发的消息序列不同,因为消息到期和收到更高优先级的消息。  

   会话必须设置消息的redelivered 标记,表示它是由于恢复而被重新转发的。  



                                                             38 / 66  

  


…………………………………………………………Page 39……………………………………………………………

                                   



4。4。12 消息的重复转发  



   JMS 提供商不能重复转发已确认消息。  

    当客户端使用AUTO_ACKNOWLEDGE 模式时,它不会直接控制消息的确认。由于这种客 

户端不能确切知道某个消息是否已经被确认,因此它们必须做好再次收到最后消费的消息的 

准备。这可能由于客户端完成它的工作恰好在防止消息确认发生失败之前引起。只有会话测 

最后消费的消息会遇到这种情况。JMSRedelivered 消息头字段将用于这种情况下被重发的消 

息。  



4。4。13 消息的重复产生  



   JMS 提供商不能生产重复的消息。这意味着生产消息的客户端可以依赖JMS 提供商来保 

证消息的消费者一个消息只会接收一次。客户端的错误不会引起提供商重复一个消息。  

   如果在客户端提交和提交方法返回期间出现错误,那么客户端不能决定事务是否被提交 

还是被回滚。当非事务性的发送一个 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 没有定义如何提供精
返回目录 上一页 下一页 回到顶部 0 0
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!