主题筛选器和操作

订阅者可以定义他们希望从主题接收的消息。 这些消息采用一个或多个命名订阅规则的形式指定。 每个规则都包含用于选择特定消息的筛选器条件,并且(可选)包含对所选消息进行批注的操作 。

所有未包含操作的规则都将使用 OR 条件进行合并,并最终在订阅上生成一条消息(即使你有多个匹配规则也是如此) 。

每个包含操作的规则都会生成消息副本。 此消息将具有名为 RuleName 的属性,其值为匹配规则的名称。 该操作可以添加或更新属性,或从原始消息中删除属性,以便在订阅中生成消息。

请考虑以下方案,其中订阅有五条规则:两条规则具有操作,另外三条没有操作。 在此示例中,如果你发送一条与所有五个规则都匹配的消息,你会在订阅上收到三条消息。 其中两条是两个包含操作的规则的消息,一条是三个不包含操作的规则的消息。

每个新创建的主题订阅都具有初始默认订阅规则。 如果未显式指定规则的筛选条件,则应用的筛选器是 true 筛选器,通过它可以将所有消息都选择到订阅中。 默认规则没有关联批注操作。

注意

本文适用于非 JMS 方案。 对于 JMS 方案,请使用消息选择器

筛选器

服务总线支持三种筛选条件:

  • SQL 筛选器
  • 布尔筛选器
  • 关联筛选器

以下部分提供了有关这些筛选器的详细信息。

SQL 筛选器

SqlFilter 包含类似 SQL 的条件表达式,它是在中转站中针对到达消息的用户定义属性和系统属性计算的。 所有系统属性在条件表达式中必须带有前缀 sys.筛选条件的 SQL 语言子集可测试是否存在属性(EXISTS)、Null 值(IS NULL)、逻辑 NOT/AND/OR、关系运算符、简单数值算术和使用 LIKE 的简单文本模式匹配。

下面是用于定义 SQL 筛选器的 .NET 示例:

adminClient = new ServiceBusAdministrationClient(connectionString);    

// Create a SQL filter with color set to blue and quantity to 10
await adminClient.CreateSubscriptionAsync(
		new CreateSubscriptionOptions(topicName, "ColorBlueSize10Orders"), 
		new CreateRuleOptions("BlueSize10Orders", new SqlRuleFilter("color='blue' AND quantity=10")));

// Create a SQL filter with color set to red
// Action is defined to set the quantity to half if the color is red
await adminClient.CreateRuleAsync(topicName, "ColorRed", new CreateRuleOptions 
{ 
	Name = "RedOrdersWithAction",
	Filter = new SqlRuleFilter("user.color='red'"),
	Action = new SqlRuleAction("SET quantity = quantity / 2;")
}

布尔筛选器

使用 TrueFilterFalseFilter,可以导致为订阅选择所有到达的消息(True),也可以导致不为订阅选择任何到达的消息(False)。 这两个筛选器派生自 SQL 筛选器。

下面是用于定义布尔筛选器的 .NET 示例:

// Create a True Rule filter with an expression that always evaluates to true
// It's equivalent to using SQL rule filter with 1=1 as the expression
await adminClient.CreateSubscriptionAsync(
		new CreateSubscriptionOptions(topicName, subscriptionAllOrders), 
		new CreateRuleOptions("AllOrders", new TrueRuleFilter()));	

关联筛选器

CorrelationFilter 包含一组条件,这些条件按照到达消息的一个或多个用户和系统属性进行匹配。 常见的用法是根据 CorrelationId 属性进行匹配,但应用程序也可以选择根据以下属性进行匹配:

  • ContentType
  • Label
  • MessageId
  • ReplyTo
  • ReplyToSessionId
  • SessionId
  • To
  • 任何用户定义的属性。

当到达消息的某个属性值等于相关筛选器中指定的值时,便存在匹配。 对于字符串表达式,比较会区分大小写。 如果指定多个匹配属性,筛选器会将它们合并为逻辑“与”条件,这意味着若要使筛选器匹配,所有条件都必须匹配。

下面是用于定义关联筛选器的 .NET 示例:

// Create a correlation filter with color set to Red and priority set to High
await adminClient.CreateSubscriptionAsync(
		new CreateSubscriptionOptions(topicName, "HighPriorityRedOrders"), 
		new CreateRuleOptions("HighPriorityRedOrdersRule", new CorrelationRuleFilter() {Subject = "red", CorrelationId = "high"} ));	

使用采用 String 参数的构造函数 CorrelationRuleFilter 创建具有关联 ID 的关联筛选器。

使用CorrelationRuleFilter默认构造函数时,可以分配系统属性(ContentTypeLabelMessageIdReplyToReplyToSessionIdSessionIdTo)和用户定义的属性来进行筛选。 要为关联筛选器指定用户定义的属性,请使用类型为 IDictionary <string, object> 的属性 Properties。 此字典的键是用于查找消息的用户定义属性。 与键关联的值是要关联的值。 下面是一个示例。

var filter = new CorrelationFilter();
filter.Label = "abc";
filter.ReplyTo = "xdeu@hotmail.com";
filter.Properties["prop1"] = "abc";
filter.Properties["prop2"] = "xyz";

注意

  • 所有筛选器都会计算消息属性。 筛选器无法评估消息正文。
  • 复杂筛选器规则需要处理能力。 具体而言,使用 SQL 筛选规则会导致订阅、主题和命名空间级别的总体消息吞吐量降低。 应用程序应尽可能选择关联筛选器而不是类似 SQL 的筛选器,因为它们的处理效率要高得多,并且对吞吐量的影响较小。

操作

使用 SQL 筛选条件,可以定义可通过添加、删除或替换属性及其值对消息进行批注的操作。 操作使用类似 SQL 的表达式,该表达式以松散的方式依赖于 SQL UPDATE 语句语法。 在消息匹配之后,在将消息选入订阅之前,对消息执行操作。 对消息属性进行的更改是复制到订阅中的消息所专有的。

下面是一个 .NET 示例,该示例创建了一个 SQL 规则,该规则所包含的操作可以在颜色为红色时更新数量。

adminClient = new ServiceBusAdministrationClient(connectionString);    

// Create a SQL filter with color set to red
// Action is defined to set the quantity to half if the color is red
await adminClient.CreateRuleAsync(topicName, "ColorRed", new CreateRuleOptions 
{ 
	Name = "RedOrdersWithAction",
	Filter = new SqlRuleFilter("user.color='red'"),
	Action = new SqlRuleAction("SET quantity = quantity / 2;")
}

重要

通过规则操作更新系统属性时,请注意,它可能会更改预期行为。 只有在队列或主题中收到消息时,才会评估某些属性。 因此,在规则操作中更新这些属性,然后在订阅中传递这些属性时,将忽略这些属性。 不过,当自动转发到另一个队列或主题时,会重新评估它们。

  • ScheduledEnqueueTime:设置或更新此属性时,订阅上将忽略此属性。
  • 重复数据删除的 MessageID:更新 MessageID 并导致重复时,订阅中不会执行重复数据删除。
  • 具有分区的 SessionID:在此方案中,会话 ID 是分区实体的分区键,用于确定消息发送到的分区。 更改规则操作中的 sessionID 意味着在消息进入分区后更改分区键。 因此,使用者在会话中可能不会收到其中一些消息。 即使使用者收到消息,由于分区键已更改,它们看起来好像来自错误的分区。

使用模式

  • 广播模式

    主题的最简单使用方案是每个订阅都获取发送到主题的每个消息的副本,这样可实现广播模式。

  • 分区模式

    分区使用筛选器以可预测且互相排斥的方式跨多个现有主题订阅分发消息。 当系统进行扩大以在功能相同的隔离舱(每个隔离舱包含总体数据的子集;例如客户配置文件信息)中处理许多不同上下文时,可使用分区模式。 借助分区,发布者可将消息提交到主题中,而无需了解分区模型。 消息随后会移动到正确的订阅,分区的消息处理程序随后会从该订阅检索它。

  • 路由模式

    路由使用筛选器以可预测、但不一定独占的方式跨主题订阅分发消息。 通过与自动转发功能相结合,主题筛选器可以用于在服务总线命名空间中创建复杂路由图,以便在 Azure 区域中进行消息分发。 通过使 Azure Functions 或 Azure 逻辑应用充当 Azure 服务总线命名空间之间的桥梁,可以创建直接集成到业务线应用程序中的复杂全局拓扑。

注意

由于 Azure 门户现在支持 Service Bus Explorer 功能,因此可以从门户创建或编辑订阅筛选器。

后续步骤

有关更多示例,请参阅服务总线筛选器示例