读书人

JMS订阅形式消息

发布时间: 2013-08-11 22:22:29 作者: rapoo

JMS订阅模式消息

?

? ? 在session.createSubscriber(Topic topic)方法中,将会创建一个"非耐久性"主题,即只有subscriber侦听时才会收到消息,当subscriber离线时,它将错过消息.session.createDurableSubscriber(Topic topic,String name)用来创建一个耐久性订阅者,这种订阅者不会错过离线时的消息,JMS Provider将会为它保留所有的消息副本(必须符合相应的消息选择器).其中参数"name"用来表示此订阅者的名字,name的值可以任意,也不允许重复.

? ? 其中耐久性订阅者,必须对connection设定ClientId且此ID全局不能重复,否则将会抛出:javax.jms.JMSException: You cannot create a durable subscriber without specifying a unique clientID on a Connection.

? ? 一个session中只能创建一个耐久性订阅者,否则将抛出异常:javax.jms.JMSException: Durable consumer is in use for client;不过一个connection下可以有多个耐久性订阅者.

? ? 如果一个connection下有多个耐久订阅者时,此时订阅者的name不能重复,否则抛出:?javax.jms.JMSException: Durable consumer is in use for client: TestClientId and subscriptionName: ..

? ??session.unsubscribe(String name)方法为取消订阅,取消当前connection下指定name的订阅者.此后JMS Provider将不会为其保存消息副本.如果你确定一个耐久订阅者不会再次激活时,你需要"取消订阅",否则JMS Provider将会一直为它保存消息副本,而且极有可能带来存储上的风险,如果磁盘或者内存消耗完毕,将会导致JMS Provider故障.

?

? ? Topic中消息副本的存储模式(数据库描述):

?

++++++++++++Consumers table+++++++++id      |       Name                      |       destinationId         |     created1                  clientID1::name1                  testTopoc               1222222222                  clientID1::name2                  testTopoc               122323232//其中Name + destinationId为唯一索引.++++++++++++Messages_handles+++++++++id      |    messagId    |     destinationId    |    consumerId  |   delivered1                 10010                 testTopic                      1                02                 10010                 testTopic                      2                0//消息的实体将会保存在其他表中,通过messageId与其关联.//此表中messageId + destinationId + consumerId为唯一索引.

??

? ? 通过这个存储模式,我们能够理解出JMS Provider是如何创建消息副本的:每创建一个耐久订阅者都将会在Consumer表中新增一条记录,当"取消订阅"之后,相应的consumer记录也会被删除;当一个Topic中新的消息生成时,将会检索consumer表中此destinationId下的所有consumer,然后为每个conusmer生成消息副本--在Message_handles表中插入一条数据;如果某个consumer消费了一条消息,将会在message_handles表中删除消息副本记录.

?

? ? 其中createDurableSubscriber(Topic topic,String name,String selector,boolean noLocal)方法中还有一个重要的参数--noLocal,此参数主要用来控制此订阅者是否接受本地消息,所谓本地消息就是当前Connection下其他publisher发送的消息(对于JMS Provider而言,就是ClientID标识),如果noLocal = true,那么意味着将只能收到其他Client发布的消息.

读书人网 >编程

热点推荐