读书人

JMS讯息选择器

发布时间: 2013-08-10 21:14:06 作者: rapoo

JMS消息选择器

? ? 消息选择器:对于消息消费者而言,可能希望接收通道中特定规则的消息,这个时候就需要使用消息选择器.

MessageConsumer consumer = session.createConsumer(replyTo,"JMSCorrelationID='" + cid + "'");

? ? 消息选择器需要在创建consumer时指定,且整个session生命周期中不能被改变;如果需要改变消费者的选择器,只能把当前consumer.close(),然后重新创建consumer实例.

? ? 对于JMS Provider而言,也会持有每个活跃的consumer以及其选择器信息.其中对于Topic而言,如果JMS Provider接收到消息后,会检测+计算每个conmser的选择器,provider对过滤结果为true的consumer创建此消息的副本,并择机发送消息给此consumer.对于Queue则稍有不同,对于每条消息首先加入队列,那么在此消息被发送时才会计算选择器,并将此消息发送给选择器计算结果为true的某个消费者.

? ? QueueReceiver,TopicSubscriber都可以在创建时指定消息选择器,一旦使用了消息选择器,此消费者只能接收到符合"选择器"要求的消息;消息选择器是一个符合SQL-92语法的表达式,其实它可以认为是sql语言中where之后的字句部分,例如"JMSCorrelationID= 'zhangsan' and amount between (10,20)";其中表达式中的比较标识符可以来自JMS消息的消息头或者属性.但是不能使用消息体中的内容.

? ? 其中JMS消息头为:JMSDeliveryMode,JMSPriority,JMSMessageID,JMSTimestamp,JMSCorrelationID,JMSType.

? ? 任何通过类似于message.setStringProperty("name","zhangsan")设置的消息属性,也可以在消息选择器中使用.

?

? ? 如果使用了消息选择器,当全局中所有的消费者都没有将某条消息覆盖,那么此消息就是"僵尸消息",它将不能被任何消费者使用,将永久驻留在JMS Provider中;如果这种"遗漏"的消息非常庞大,当然会带来致命的风险.例如下述2个消费者的选择器:"age > 25" "age < 25".如果此通道中只有这2中选择器的消费者,那么会导致"age = 25"的消息无法被传送.解决这个问题的方式有:

? ? 1) 创建一个额外的补充消费者,这个消费者不设置任何选择器

? ? 2) 为持久化的消息设定timeToLive属性,可以控制消息消亡的时间,以避免此类型消息的沉积.因为消息的沉积,必将带来队列深度问题.

?

? ? 其实换个角度考虑,使用消息选择器能解决的问题,仍然可以通过"多目的地"的方式解决,比如将"age > 25"的消息发送到queue1,将"age <25"的发送到queue2."多目的地"通道是一种良好的设计,它更细颗粒度的控制了消息的分类,但是它要求Client端需要更多的关注消息的属性和通道的关系.通常情况下,我们根据消息的类型不同,来使用"多目的地"方式,然后在"同一类"消息中使用"选择器",比如:我们有一个订单系统用来发送订单内容,订单类型有"虚拟商品订单"/"图书商品订单"/"电器商品订单",那么在这个维度上,我可以为每种不同类型的订单消息,创建一个"目的地",那么非常方便不同的业务应用来获取它们感兴趣的订单类型;同时每个订单,都有不同的订单状态(待付款,已付款,退款),那么对于这种维度,我们可以使用消息选择器,比如"财务退款中心"的系统对"退款"状态的订单感兴趣.

?

1 楼 jzinfo 2 小时前 到底是使用多个destination来作为不同类型业务的消息通道

还是使用一个destination使用selector来区分不同业务类型消息,这2种方法各有千秋。

需要说明的是,在某些情况下,使用selector会带来一定的性能问题。

EAI中通常会使用前者解决方案,基于内容的消息路由总线可以将各自特定的消息路由到不同的消息通道,这更简洁明了。

同一个destination中包含不同类型的消息,使用selector来区分的话,有一种场景,那就是消息类型的维度划分比较细,大的维度的消息使用多个destination,具体到某一个destination中存储的消息中区分更细的消息类型,会考虑使用selector。

在大型的消息传递解决方案中,这2种解决方法,有时会相辅相成,互相存在。

读书人网 >编程

热点推荐