跳到主要内容

选择器

选择器允许客户端应用程序指定它们感兴趣接收的消息,这些消息由消息的标头字段和属性值决定。选择器是一个最多 2,000 字节的字符串,使用 SQL92 的一个子集的条件表达语法。有关消息选择器语法的详细信息,请参阅《Java 消息服务规范 - 1.1 版》。所有 Solace 消息 API 都支持选择器。

当使用选择器时,只有当选择器在消息的标头字段和属性值替换选择器中相应的标识符时计算结果为 true,客户端才会接收消息。事件代理会过滤掉不匹配的消息。

可以选择器设置的有:

  • 绑定到队列或主题订阅的消费者。参阅为消费者设置选择器。
  • 用于检查队列上的消息而不消费它们的浏览器。参阅浏览消息。

使用选择器时的性能注意事项

尽管完全支持选择器,但通常使用无选择器的主题匹配可以实现最佳性能。在许多情况下,可以将原本要在选择器中选择的消息属性包含在主题层次结构中。然后,可以使用主题订阅和主题订阅异常来匹配主题中的相关级别,以实现类似选择器表达式的匹配。

主题订阅和主题订阅异常支持在级别内使用通配符和前缀匹配。通过通配符、异常以及为队列或主题端点指定多个订阅或异常的能力,可以实现类似 AND、OR 和 NOT 的匹配操作。

使用选择器从深度队列检索消息时,也需要考虑性能。Solace 事件代理需要检索队列中的每条消息,可能来自磁盘,以根据消费者的表达式评估其内容。如果队列非常深,可能需要几秒钟才能找到第一条匹配的消息。大消息的检索和评估也需要更长时间。这种行为可能会影响事件代理的消息转储性能,从而可能影响未使用选择器的客户端。当使用主题订阅进行过滤时,这些挑战被消除,因为过滤发生在事件代理将消息添加到队列之前。

一般来说,应尽可能避免使用选择器。

JMS和Saydo API之间的选择器标识符映射

下表列出了标准 JMS 标识符及其等效的 Solace 标识符。Solace 标识符作为保留键编码在 Solace SMF 消息的结构化数据映射中。两种类型的标识符都可以用来定义选择器。

例如,JMSCorrelationID 在映射中使用键 ci 编码。如果您使用 JMS API,并且只想匹配相关 ID(这是一个字符串)为 "myCorrelationId" 的消息,您可以像这样编写 JMS 中的选择器表达式:

JMSCorrelationID = 'myCorrelationId'

如果您使用的是 Solace 消息 API,您可以像这样编写相同的表达式:

ci = 'myCorrelationId'

JMS 可能没有为某些 Solace 标识符设置方法,例如消息序列号(sn),但仍然可以对 sn 标识符进行选择。

JMS 标识符Solace 标识符相关的 Solace 消息属性
消息标头字段JMSCorrelationIDciCorrelationId
JMSDeliveryModeNADeliveryMode
JMSMessageIDmiApplicationMessageId
JMSPriorityNAPriority
JMSReplyTortReplyTo
JMSTimestamptsSenderTimestamp
JMSTypemtApplicationMessageType
NAsiSenderID
NAsnSequenceNo
NAexExpiration
NActHttpContentType
NAceHttpContentEncoding
JMS 定义的属性JMSXGroupSeq视为用户指定Solace 消息 API 可以将 JMSX 属性作为用户属性访问,属性名称与 JMS 中使用的相同。
JMSXGroupID视为用户指定
JMSXUserID<client-username>
仅当使用基本客户端身份验证且启用了 jmsx-user-id-enabled 连接工厂属性时,才提供 JMSXUserID 属性。
用户定义的消息属性用户指定用户指定NA

选择器标识符

为消费者设置选择器

可以选择器设置的有使用保证传输的持久主题订阅者或使用保证传输的队列的消息消费者。(不能为使用直接传输的消费者设置消息选择器。如果配置了消息选择器,将返回配置异常。)

每种类型消费者的选择器功能不同:

  • 持久主题订阅者 当为持久主题订阅者定义选择器时,其标头字段和属性与选择器中定义的相应标识符不匹配的消息不会排队到持久主题订阅。因此,选择器作为持久主题订阅的入口过滤器。

如果持久主题订阅者断开连接,并且更改了其选择器,则在主题订阅者再次绑定之前,从持久主题订阅中移除所有现有消息。为了防止在持久主题订阅者重新绑定时移除持久主题订阅的所有消息,使用的必须与之前绑定时使用的选择器完全相同。

  • 队列消费者 当消费者绑定到独占队列时,其可以消费的消息由消费者定义的选择器过滤。被消费者选择器排除的消息保留在队列中,并且可以由后续可能绑定的不同选择器或无选择器的消费者消费。选择器作为队列的出口过滤器。

当消费者绑定到非独占队列时,根据其选择器,绑定的客户端以轮询方式消费消息。一旦消息被消费,它就不再对后续客户端可用。

以下代码展示了如何为队列上的消费者定义选择器:

Connection connection = null;
queue = session.createQueue("queue");
selector = new String("phone NOT LIKE '12%3'");
consumer = session.createConsumer(queue, selector);