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

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

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





             TopicPublisher                         MessageProducer  



             TopicSubscriber                       MessageConsumer  



6。2  Pub/Sub 延时  



    由于在所有的Pub/Sub 系统中通常都会有一些延时,订阅者实际看见的消息的时间根据 

JMS 提供商产生新的订阅者和提供商在转发过程中保留消息的时间长度会有很大的不同。  

    例如,由于新的订阅者传播到整个系统会花费一些时间,因此来自远方发布者的消息可 

能会被错过。当创建新的订阅者时,它可以接收在创建之间发送的消息,因为提供商可能还 

没有让订阅者可以获取这些消息。  



                                                                         45 / 66  

  


…………………………………………………………Page 46……………………………………………………………

                                    



   JMS 没有定义在pub/sub 提供商调整到新的客户端的间隔期内的语义。JMS 语义只应用 

到达到“稳定状态”的提供商。  



6。3  永久订阅  



    非永久订阅维持着订阅者对象的生命。这意味着客户端将只能看见在订阅者是活动时发 

布到主题的消息。如果订阅者是不活动的,那么它将错过发布到主题的消息。  

    订阅者可以以高负荷的成本来使用永久订阅。永久订阅者用一个唯一标识向 JMS  注册 

一个永久订阅。使用同一个标识的后续订阅者对象重新使用前一个订阅者使用过的订阅,这 

个订阅的状态是前一个订阅者留下的。如果永久订阅没有活动的订阅者,则 JMS                        保留订阅 

的消息直到它们被订阅接收或到期。  

    所有的JMS 提高商必须能够动态创建和删除永久订阅的JMS 应用。另外,某些JMS 提 

供商可以提供管理配置永久订阅的工具。如果永久订阅已经被配置,它可以默默覆盖由客户 

端指定的订阅。  

    不活动的永久订阅是一个存在但当前还没有消息消费者向它订阅的永久订阅。  



6。4  主题(Topic )管理  



    某些产品要求主题是静态定义、要与权限控制相关联,等等;其他的甚至没有主题管理 

的概念。  

   JMS 没有定义创建、管理或删除主题的工具。  

    一种特殊类型的主题是TemporaryTopic ,它用于创建一个对于TopicConnection 来说是唯 

一的Topic 。参见节6。6  “临时主题(TemporaryTopic )”了解详细信息。  



6。5  Topic  



   Topic 对象封装了提供商特有的主题名。它用于在JMS 方法中指定主题标识。  

    许多Pub/Sub 提供商将主题组织成层级形式,并提供很多选项来订阅层级的部分主题。 

JMS 对Topic 对象代表什么没有限制。它可能是主题层级的叶子,或者可能是层级的较大部 

分(用于订阅信息的大类)。  

    主题的组织和订阅授权都是Pub/Sub 应用架构很重要的部分。JMS 没有指定如何实现它 

们的策略。如果应用使用了提供上特有的分组机制,那么它应当记录它。如果应用使用不同 

的提供商,那么管理员负责构造相等的主题架构和创建相等的Topic 对象。  



6。6  TemporaryTopic  



   TemporaryTopic 是一个唯一的Topic 对象,它为Connection 或TopicConnection 永久化而 

创建。它是系统定义的Topic ,只能被创建它的Connection 或TopicConnection 消费。  

    根据定义,向一个临时主题创建永久订阅是没有意义的。如果这么做就是程序错误,它 

可能会也可能不会被JMS 提供商检测到。  

    参见节4。4。3  “创建临时目的地”了解详细信息。  



                                                                46 / 66  

  


…………………………………………………………Page 47……………………………………………………………

                                         



6。7  TopicConnectionFactory  



    客户端使用TopicConnectionFactory 来创建带JMS Pub/Sub 提供商的TopicConnection 。  

    参见节4。2  “受管理对象”了解JMS ConnectionFactory 对象的更多信息。  



6。8  TopicConnection  



    TopicConnection 是一个连接到 JMS  Pub/Sub        提供商的活动连接。客户端使用 

TopicConnection 来创建一到多个用于生产和消费消息的TopicSession 。  

    参见节4。3  “Connection ”了解更多信息。  



6。9  TopicSession  



    TopicSession  提供了创建TopicPublisher 、TopicSubscriber  和TemporaryTopic  的方法。它 

也提供了用于删除客户端永久订阅的unsubscribe 方法。  

    如果已经接收到消息但消息在TopicSession 终止时还没有被确认,则永久TopicSubscriber 

必须保留和重发这些消息;非永久订阅不需要这么做。  

    参见节4。4  “Session ”了解更多信息。  



6。10  TopicPublisher  



    客户端使用TopicPublisher 向一个topic 发布消息。TopicPublisher 是JMS MessageProducer 

的 Pub/Sub   变量。可以使用 MessageProducer         想一个 Topic    发送消息。参见节 4。6 

 “MessageProducer”了解公共特性的描述。  



6。11  TopicSubscriber  



    客户端使用 TopicSubscriber     来接收已发布到主题的消息。TopicSubscriber               是 JMS  

MessageConsumer 的Pub/Sub 变量。参见节4。5  “MessageConsumer”了解更多信息。  

    普通的TopicSubscriber 不是永久性的。它们只接收它们是活动时被发布的消息。  

    被订阅者的消息选择器过滤掉的消息永远不会被订阅者接收到。从订阅者的角度来看, 

这些消息是不存在的。  

    在某些情况下,连接可以既是到主题的发布又是到主题的订阅。订阅者的NoLocal 属性 

可以让订阅者抑制转发由它自己的连接发布的消息。  

    TopicSession 可以为每个目的地创建多个TopicSubscriber ,它将目的地的每个消息都转发 

到符合接收条件的TopicSubscriber 。这些都工作在消息的复制品上,而不互相影响;确认一 

个消息不会确认其他的消息;一个消息可能被立刻转发,但另一个可能等待消费者处理完它 

前面的消息。  



                                                                          47 / 66  

  


…………………………………………………………Page 48……………………………………………………………

                                    



6。11。1 永久TopicSubscriber  



    如果客户端需要接收发布到主题上的所有消息,包括订阅者是不活动时发布的消息,那 

么它使用永久TopicSubscriber 。永久TopicSubscriber 可以由Session 或TopicSession 创建。JMS 

保留永久订阅的记录并保证来自Topic 的发布者的所有消息都被保留,直到这些消息被永久 

订阅者确认或它们到期。  

    使用永久订阅的会话必须总是提供同一个客户端标识。另外,每个客户端必须指定唯一 

标识(在客户端标识符中)它创建的每个永久订阅的名字。一次只能有一个会话可以有一个 

特殊永久订阅的TopicSubscriber 。参见节4。3。2  “客户端标识”了解更多信息。  

    客户端可以通过创建一个具有相同名字和新主题和/或消息选择器或 NoLocal  属性的永 

久TopicSubscriber 来改变一个存在的永久订阅。改变一个永久订阅相当于删除并重新创建它。  

    Session 和TopicSession 提供了unsubsribe 用于删除它们客户端创建的永久订阅。这回删 

除由提供商代表订阅者维护的状态。对客户端来说,当永久订阅有活动的 TopicSubscriber 

或者当被接收到的消息是当前事务的一部分或者还没有在会话中确认时,删除一个永久订阅 

是错误的。  



6。12  恢复和重发  



    非永久订阅者的未确认消息应当能够在非永久订阅者生存时被恢复。当非永久订阅者终 

止时,等待它的消息很可能被丢弃而不管是否被确认。  

    只有永久订阅可以可靠地恢复未确认消息。  

    向转发模式是PERSISTNET 的主题发送消息不会改变恢复和重发的模式。为了保证转发, 

TopicSubscriber 应当设置一个永久订阅。  



6。13  管理订阅  



    理想情况下,发布者和订阅者都是在它们被创建时由提供商动态注册。从客户端视角来 

看,总是这样的。从管理员的角度看,可能需要其他任务来支持发布者和订阅者的创建。  

    为消息存储分配的资源的数量和资源过量的结果在JMS  中没有定义。  



6。14  TopicRequestor  



   JMS 提供了TopicRequestor 帮助类来简化服务请求。  

   TopicRequestor 构造器需要传入 TopicSession 和目的地主题。它为响应创建了一个 

TemporaryTopic ,并提供了发送请求消息的request()方法然后等待回复。  

    这是最基本的请求/ 响应抽象,它可以满足大多数的用途。JMS                 提供者和客户端可以自 

由地创建多种专业版本。  



6。15  可靠性  



    当主题的所有消息必须被接收时,应当使用永久订阅。JMS 保证在永久订阅者不活动时 



                                                                 48 / 66  

  


…………………………………………………………Page 49……………………………………………………………

                                      



保留发布的消息,并在订阅者活动后将消息转发给它。  

    非永久订阅者只应当用于可以接受丢失的情况。  

                             表6�2 Pub/Sub 可靠性  



        如何发布                   非永久订阅                     永久订阅  



     NON_PERSISTENT      最多一次(如果不活动则丢                    最多一次  

                                  失)  



       PERSISTENT        一次只有一个(如果不活动则                 一次只有一个  

                                 丢失)  



7  JMS 异常  



7。1  概述  



    本章对JMS 异常处理做了概述并定义了标准的JMS 异常。  



7。2  JMSException  



    JMS 定义了JMSException 作为JMS 方法抛出的异常的根类。JMSException 是一个受检查 

异常,捕捉它就可以处理所有JMS 相关的异常。JMSException 提供了下面的信息:  

    z  提供商特有的描述错误的字符串——这个字符串是标准的 java                      异常消息,可用 

       getMessage()获得这个消息。  

    z  提供商特有的字符串型错误代码。  

    z  对另一个异常的引用——一个 JMS           异常通常是由底层问题引起。如果合适,底层 

       异常可以被关联到JMS 异常。  

    JMS 方法在它们的标识符中只包含JMSException 。JMS 方法可以抛出任意的标准JMS 异 

常,以及JMS 供应商特有的异常。JMS 方法的javadoc 只给出了必需的异常情况。  



7。3  标准异常  



    除了JMSException 外,JMS 定义了几个其他异常,它们标准化了基本错误原因的报告。  

    只有几种情况必须抛出指定的JMS 异常。这些情况在异常描述中用单词“必须”标出。 

这些情况都是唯一的,在这些情况下客户端逻辑应当根据特定的问题抛出特定的JMS 异常。  

    在其他情况下,强烈建议JMS 提供商尽可能使用标准的异常。JMS 提供商如果需要也可 

以从这些异常中提取供应商特有的异常。  

    JMS 定义了下面的标准异常:  

    z  IllegalStateException:当在不合法或不合适的时间,或提供商没有处于处理请求操 

       作的合适状态,则抛出这个异常。例如,如果 Session。mit()在非事务会话中被 

       调用,则必须抛出这个异常。当调用与域不匹配的方法时,例如调用 

       TopicSession。CreateQueueBrowser() ,必须抛出这个异常。  

    z  JMSSecurityException :当提供商拒绝客户端提交的用户名/密码时必须抛出这个异 



                                                                   49 / 66  

  


…………………………………………………………Page 50……………………………………………………………

                                     



       常。它也可以用于安全限制阻止方法完成的情况。  

    z  InvalidClientException:当客户端企图设置连接的客户端标识,但提供商拒绝了这个 

       标识的值时,就必须抛出这个异常。  

    z  InvalidDestinationException:当提供商不能识别给定的目的地或目的地不再有效时, 

       必须抛出这个异常。  

    z  InvalidSelectorException:当 JMS 客户端企图用无效的语法向提供商提供消息选择 

       器时,必须抛出这个异常。  

    z  MessageEOFException:当正在读取StreamMessage 或ByteMessage 时到达了不期望 

       的流结尾,则必须抛出这个异常。  

    z  MessageRormatException:当JMS 客户端企图使用消息不支持的数据类型或企图将 

       消息的数据读作错误的类型时,必须抛出这个异常。当消息属性值发生同样的类型 

       错误时也必须抛出这个异常。例如,如果 StreamMessage。writeObject()被给了不支 

       持的类或如果 StreamMessage。readShort()用于读取布尔值,则必须抛出这个异常。 

       如果提供商被给了不能接受的类型,则也必须抛出这个异常。注意,一个特殊的情 

       况是当企图读取不正确格式的 String              数据作为数值型值时,必须抛出 

       java。lang。NumberFormatException 。  

    z  MessageNotReadableException:当JMS 客户端企图读一个只可写的消息时必须抛出 

       这个异常。  

    z  MessageNotWriteableException:当JMS  客户端企图写一个只可读的消息时必须抛 

       出这个异常。  

    z  ResourceAllocationException:当提供商不能定位方法请求的资源时必须抛出这个异 

       常。例如,当由于JMS 提供商资源缺失而导致调用createTopicConnection 失败时应 

       当抛出这个异常。  

    z  TransactionProgressException :当由于事务处于处理中而导致操作无效时抛出这个 

       异常。例如,当会话时分布式事务的一部分时调用 Session。mit()应当抛出这个 

       异常。  

    z  TransactionRolledBackException :当调用Session。mit 导致当前事务回滚时必须抛 

       出这个异常。  



8  JMS 应用服务器工具  



8。1  概述  



    本章描述用于并发处理订阅消息的JMS 工具。也定义了JMS 提供商如何支持JTS 可感知 

的会话。这些工具主要由JMS 提供商使用。  

    如果JMS 客户端使用JTS 可感知工具来进行客户端编程,则它可能是不可移植的,因为 

不要求JMS 提供商支持这些接口。  

    在本章中描述的工具是JMS  的一个特殊类别。它们是可选的,可能只有部分JMS 提供 

商对它们提供支持。  



                                                                   50 / 66  

  


…………………………………………………………Page 51……………………………………………………………

                                        



8。2  并发处理订阅的消息  



    JMS 提供了一个特殊的工具用于创建MessageConsumer,它可以并发的消费消息。  

    这个工具将这项工作分成三个角色:  

    z   JMS 提供商——用于转发消息。  

    z   应用服务器——用于创建消费者和管理由并发MessageListener 对象使用的线程。  

    z   应用——用目的地和可选的消息选择器定义一个订阅,并提供一个单线程的 

        MessageListener 类来消费它的消息。应用服务器将构造这个类的多个对象来并发消 

        费消息。  



8。2。1 Session  



    会话提供了应用服务器使用的三个方法:  

    z   setMessageListener() 和 getMessageListener() ——会话的 MessageListener 通过 

        ConnectionConsumer 消费分配到这个会话的消息,如后面的几个段落描述。  

    z   run()——会话的MessageListener 依次处理由ConnectionConsumer 分配到会话的消 

        息。当监听器从最后一个消息处理返回时,run()返回。  

    应用服务器通常被给一个 MessageListener 类,它包含了由应用程序员编写的处理消息 

的单线程代码。应用服务器也被给监听器要消费消息的目的地和消息选择器。  

    应用服务器将负责创建处理消息处理的JMS Connection,ConnectionConsumer 和Session 。 

应用服务器将按需创建MessageListener 实例并将它们注册到它自己的会话中。  

    由于许多监听器需要使用会话的服务,因此监听器很可能要求将它的会话传入到它的构 

造器中。  



8。2。2 ServerSession  



    ServerSession 是一个由应用服务器实现的对象。应用服务器使用它来将一个线程和一个 

JMS 会话关联起来。  

    ServerSession 实现了两个方法:  

    z   getSession()——返回ServerSession 的JMS 会话。  

    z   start()——启动ServerSession 线程的执行,并执行关联的JMS 会话的run 方法。  



8。2。3 ServerSessionPool  



    ServerSessionPool 是一个由应用服务器实现的对象,它提供了用于处理 

ConnectionConsumer 的消息的ServerSession 池。  

    它只有一个方法是getServerSession() 。这个方法从池中删除一个ServerSession 并将它返 

回给调用者(假定是ConnectionConsumer ),用于消费一个或多个消息。  

    JMS 没有说明如何实现池。它可能是一个静态的ServerSession 池,或者它可以使用更专 

业的算法来按需动态创建ServerSession 。  

    如果ServerSessionPool 没有了ServerSession,那么getServerSession()方法可能阻塞。如 



                                                                       51 / 66  

  


…………………………………………………………Page 52……………………………………………………………

                                         



果ConnectionConsumer 被阻塞,那么它不能转发新的消息直到ServerSession 返回。  



8。2。4 ConnectionConsumer  



    对于应用服务器来说,连接提供了创建 ConnectionConsumer  的专用工具。它消费的消 

息由目的地和消息选择器指定。另外,ConnectionConsumer 必须交给ServerSessionPool 用于 

处理它的消息。指定 maxMessages            值用于限制 ConnectionConsumer       一次可以加载到 

ServerSession 会话的消息数量。  

    通常,当拥堵轻微时,ConnectionConsumer 从池中得到一个ServerSession,用一个消息 

加载它的会话,然后启动它。当拥堵严重时,消息可能被退回。如果发生退回, 

ConnectionConsumer 可以用多个消息来加载每个 Session 。这减少了线程上下文的切换,减 

小了某些消息处理排序时资源的使用。  



8。2。5 ConnectionConsumer 如何使用ServerSession  


返回目录 上一页 下一页 回到顶部 赞(9) 踩(10)
快捷操作: 按键盘上方向键 ← 或 → 可快速上下翻页 按键盘上的 Enter 键可回到本书目录页 按键盘上方向键 ↑ 可回到本页顶部!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!