Compartilhar via

主题筛选器和操作

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

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

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

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

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

注意

本文适用于非Java消息服务(JMS)方案。 对于 JMS 方案,请使用消息选择器

筛选器

Service Bus支持三种类型的筛选器:

  • 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 充当布尔筛选器。 TrueFilter 会选择订阅的所有到达消息,FalseFilter 不会选择任何到达的消息。 这两个筛选器派生自 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"} ));	

使用带有参数CorrelationRuleFilterString构造函数来创建具有关联 ID 的关联筛选器。

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

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 意味着在消息进入分区后更改分区键。 因此,使用者在会话中可能不会收到其中一些消息。 即使使用者收到消息,由于分区键已更改,它们似乎来自错误的分区。

使用模式

  • 广播模式

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

  • 分区模式

    分区使用筛选器以可预测且互相排斥的方式跨多个现有主题订阅分发消息。 在将系统横向扩展以便在多个功能完全相同的隔离舱中处理各种不同的上下文时,请使用分区模式,每个隔离舱都包含整体数据的一个子集。 例如,客户个人资料信息。 借助分区,发布者可将消息提交到主题中,而无需了解分区模型。 消息随后会移动到正确的订阅,分区的消息处理程序随后会从该订阅检索它。

  • 路由模式

    路由使用筛选器以可预测、但不一定独占的方式跨主题订阅分发消息。 与 auto forwarding 功能结合使用,主题筛选器可用于在Azure区域内的消息分发的Service Bus命名空间中创建复杂的路由图。 通过使用Azure Functions或Azure Logic Apps作为Azure Service Bus命名空间之间的桥梁,可以创建复杂的全局拓扑,并直接集成到业务线应用程序中。

注意

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

后续步骤

有关更多示例,请参阅Service Bus筛选器示例