消息选择器:对于消息消费者而言,可能希望接收通道中特定规则的消息,这个时候就需要使用消息选择器.
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端需要更多的关注消息的属性和通道的关系.通常情况下,我们根据消息的类型不同,来使用"多目的地"方式,然后在"同一类"消息中使用"选择器",比如:我们有一个订单系统用来发送订单内容,订单类型有"虚拟商品订单"/"图书商品订单"/"电器商品订单",那么在这个维度上,我可以为每种不同类型的订单消息,创建一个"目的地",那么非常方便不同的业务应用来获取它们感兴趣的订单类型;同时每个订单,都有不同的订单状态(待付款,已付款,退款),那么对于这种维度,我们可以使用消息选择器,比如"财务退款中心"的系统对"退款"状态的订单感兴趣.
通过上述图示,我们可以简单的理解"多目的地(multi destination)" 和消息选择器的使用场景.
还有一个很重要的因素影响着这两种方式的选择:消息"滞留"的速率..我们通过上述讲解,已经知道了消息选择器的表达式,是在JMS Server端计算的对于queue而言,每次消息的发送,都意味着需要对message属性内容进行一次拆解和表达式的计算(需要声明:消息的内容在存储上并非严格结构化和可索引化的),当消息的发送密度相当高时,这种计算开支也是不容忽略的,这种计算潜在了放缓了消息的消费速度,而且当一个通道中,多个选择器类型的消息消费速度相差较大时(从消息到达消费者,然后消息确认信号返回.比如"退款"类型的消息比较耗时,但是"取消订单"执行较快),这种隐式的消息沉淀,也会加剧队列深度,从而拖累整个通道的消息消费速率.
"多目的地"意味我们需要创建更多的通道(Topic,或者queue),在一定的程度上,我们能够通过这种方式来规避一些"单通道队列深度"问题;但是通道个数越多,其实对JMS Provider的性能考验也是很深刻的.一个通道在消息的分发机制中,将需要一个独立的线程来负责,此线程维护着内存消息队列和消费者列表;那么当活跃的通道越多,那么server的资源压力就会严峻.很多时候,我们需要在"通道个数" "通道中消息密度"之间做个平衡.
相关推荐
- **JMS消息选择器**:允许消费者根据特定条件选择接收消息。 - **消息传递方法**:分为NON_PERSISTENT和PERSISTENT,分别表示非持久性和持久性消息,影响消息在服务器故障后的存活能力。 - **消息确认方法**:包括...
**Spring与JMS消息传递** 在Java世界中,Java Message Service (JMS) 是一个标准接口,用于在分布式环境中...在实际项目中,结合具体的业务需求,可以灵活选择合适的模式和策略来利用Spring和JMS实现高效的消息通信。
- **消息选择器**:允许消费者只接收满足特定条件的消息。 - **JMS管理**:通过JMX(Java Management Extensions)管理JMS资源。 通过理解并熟练掌握上述内容,你将在WebLogic环境中成功地利用JMS进行消息传递,...
6. **消息过滤与选择器**:在ActiveMQ中,消息消费者可以通过JMS消息选择器来过滤消息。源码可以展示这些选择器的解析和执行逻辑。 7. **事务处理**:ActiveMQ支持本地JMS事务和分布式JTA事务。查看源码可以理解...
4. **消息过滤**:通过使用JMS消息选择器,用户可以定义接收特定消息的条件,从而实现消息过滤。 5. **消息优先级**:ActiveMQ支持消息优先级,使得具有较高优先级的消息能优先被处理。 6. **事务支持**:ActiveMQ...
在IT行业中,Java消息服务(Java Message Service,简称JMS)是一种标准,它定义了应用程序如何创建、发送、接收和读取消息的标准API。IBM MQ是IBM提供的一个强大的消息中间件,它允许分布式系统中的不同组件通过...
**JMS AVI转换器** 是一款专为用户设计的高效视频处理工具,主要用于将不同格式的视频文件转换成AVI格式。这款软件不仅具备基本的转换功能,还提供了视频分割和合并的能力,使得用户可以按照自己的需求对视频进行...
9. **消息选择器(Message Selector)**:消费者可以通过消息选择器只接收符合特定条件的消息。 以Apache Geronimo的JMS实现ActiveMQ为例,ActiveMQ是一个开源、高性能的消息中间件,它支持JMS 1.1和JMS 2.0规范。...
7. **消息选择器**: 如果需要,消费者还可以使用消息选择器来过滤接收到的消息。例如,只接收满足特定条件(如消息头属性)的消息。 8. **事务管理**: JMS还支持事务,确保消息的可靠传递。生产者可以将一组消息放...
5. 配置和定制:Spring JMS提供了一系列的配置选项,如目的地的定义、事务策略、消息选择器等,理解这些配置如何影响Spring JMS的行为。 通过对Spring JMS源码的深入学习,我们可以更深入地理解其工作原理,从而更...
12. **选择器(Selector)**:在发布/订阅模型中,消费者可以通过选择器过滤收到的消息,只接收满足特定条件的消息。 总的来说,JMS1.1规范为Java开发者提供了一套统一的API,便于在分布式系统中构建可靠的、基于...
- **消息选择器**:允许消费者仅接收满足特定条件的消息。 通过阅读JMS入门文档,你可以了解如何配置和使用JMS API来实现这些功能,并理解其在实际项目中的应用方式。对于初学者来说,这些文档会提供一个良好的...
- 消费者可以使用消息选择器来过滤接收到的消息,只处理满足特定条件的消息。 JMS是Java开发者在设计分布式系统时的重要工具,通过理解并熟练掌握JMS,你可以构建出高效、可靠的分布式应用。"JMS简明教程.pdf"这份...
在实际应用中,JMS还提供了各种特性,如持久化消息(确保即使服务器重启也不会丢失消息)、消息选择器(允许消费者仅接收满足特定条件的消息)、事务支持(保证消息的一致性)以及消息确认(生产者或消费者确认消息...
6. **消息选择器**:如何使用消息选择器来过滤接收的消息,只处理符合特定条件的消息。 7. **故障转移和高可用性**:了解JMS服务器如何确保高可用性和故障恢复机制。 8. **最佳实践**:包括如何设计健壮的JMS应用,...
- **消息选择器**:消费者可以使用消息选择器过滤接收的消息,只处理满足特定条件的消息。 - **消息组**:允许将消息分组,确保同组内的消息按顺序处理。 - **消息优先级**:消息可以设置优先级,高优先级的消息...
而Spring JMS(Java Message Service)则是Spring框架中处理消息传递的一个关键模块,主要用于实现应用程序之间的解耦和异步通信。本篇将主要探讨在不依赖于JNDI(Java Naming and Directory Interface)的情况下,...
MessageConsumer可以使用消息选择器来过滤接收到的消息,仅处理满足特定条件的消息。 **9. JMS API使用示例** 创建JMS连接,然后创建Session,根据需求创建MessageProducer或MessageConsumer,编写代码来发送和接收...