Amazon Simple Notification Service
开发人员指南
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

Amazon SNS 订阅筛选策略

订阅筛选策略允许您指定属性名称并为每个属性名称分配一个值列表。有关更多信息,请参阅 消息筛选

当 Amazon SNS 根据订阅筛选策略评估消息属性时,它会忽略策略中未指定的消息属性。

在以下条件下,一个订阅接受一条消息:

  • 筛选策略中的每个属性名称均与分配给消息的一个属性名称匹配。

  • 对于每个匹配的属性名称,以下各项之间至少存在一个匹配项:

    • 筛选策略中的属性名称的值

    • 消息属性

包含属性的消息示例

下面的示例演示由发布客户事务的 Amazon SNS 主题所发送的消息负载。MessageAttributes 字段包含用于描述事务的属性:

  • 客户的兴趣

  • 存储名称

  • 事件状态

  • 购买价格 (USD)

由于此消息包含 MessageAttributes 字段,因此,任何包含筛选策略的主题订阅均可选择接受或拒绝此消息。

{ "Type": "Notification", "MessageId": "a1b2c34d-567e-8f90-g1h2-i345j67klmn8", "TopicArn": "arn:aws:sns:us-east-2:123456789012:MyTopic", "Message": "message-body-with-transaction-details", "Timestamp": "2019-11-03T23:28:01.631Z", "SignatureVersion": "4", ", "Signature": "signature", "UnsubscribeURL": "unsubscribe-url", "MessageAttributes": { "customer_interests": { "Type": "String.Array", "Value": "[\"soccer\", \"rugby\", \"hockey\"]" }, "store": { "Type": "String", "Value":"example_corp" }, "event": { "Type": "String", "Value": "order_placed" }, "price_usd": { "Type": "Number", "Value":210.75 } } }

有关将属性应用于消息的信息,请参阅 Amazon SNS 消息属性

示例筛选策略

以下筛选策略基于消息的属性名称和值接受或拒绝消息。

接受消息的策略

以下订阅筛选策略中的属性与分配给示例消息的属性匹配。

如果此策略中的任一属性与分配给该消息的属性不匹配,则此策略将拒绝该消息。

{ "store": ["example_corp"], "event": [{"anything-but": "order_cancelled"}], "customer_interests": [ "rugby", "football", "baseball" ], "price_usd": [{"numeric": [">=", 100]}] }

拒绝消息的策略

以下订阅筛选策略在其属性与分配给示例消息的属性之间存在多个不匹配项。由于消息属性中不存在 encrypted 属性名称,因此该策略属性会导致消息被拒绝,而不管分配给它的值如何。

如果存在任何不匹配项,则策略将拒绝消息。

{ "store": ["example_corp"], "event": ["order_cancelled"], "encrypted": [false], "customer_interests": [ "basketball", "baseball" ] }

筛选策略约束

在创建筛选策略时,请记住以下约束:

  • 对于 String 数据类型而言,策略和消息之间的属性比较区分大小写。

  • 数值策略属性的值可以介于 -109 和 109 之间,精确至小数点后 5 位数。

  • 各值的组合总和不能超过 150。通过将每个数组内所含值的个数相乘来计算总的组合数。

    考虑以下策略:

    { "key_a": ["value_one", "value_two", "value_three"], "key_b": ["value_one"], "key_c": ["value_one", "value_two"] }

    第一个数组有三个值,第二个数组有一个值,第三个数组有两个值。总组合数的计算方法如下所示:

    3 x 1 x 2 = 6
  • Amazon SNS 仅将策略属性与具有以下数据类型的消息属性进行比较:

    • String

    • String.Array

    • Number

  • Amazon SNS 忽略具有 Binary 数据类型的消息属性。

  • 筛选策略的 JSON 可包含:

    • 用引号引起来的字符串

    • 数字

    • 不带引号的关键字 truefalsenull

  • 在使用 Amazon SNS API 时,必须将筛选策略的 JSON 作为有效的 UTF-8 字符串传递。

  • 一个筛选策略最多可具有 5 个属性名称。

  • 策略的最大大小为 256 KB。

  • 默认情况下,每个区域的每个 AWS 账户最多可使用 200 个筛选策略。要提高此限制,请提交提高限制请求

属性字符串值匹配

您可以使用字符串值来匹配消息属性和筛选消息。在 JSON 策略中,用双引号将字符串值引起来。

您可以使用以下字符串操作来匹配消息属性。

精确匹配(白名单)

在策略属性值与一个或多个消息属性值匹配时,会进行精确匹配。

考虑以下策略属性:

"customer_interests": ["rugby", "tennis"]

它匹配以下消息属性:

"customer_interests": {"Type": "String", "Value": "rugby"}
"customer_interests": {"Type": "String", "Value": "tennis"}

但是,它不匹配以下消息属性:

"customer_interests": {"Type": "String", "Value": "baseball"}

Anything-But 匹配(黑名单)

当策略属性值包含关键字 anything-but 时,它匹配 包含任一策略属性值的任何消息属性。

考虑以下策略属性:

"customer_interests": [{"anything-but": ["rugby", "tennis"]}]

它匹配以下任一消息属性:

"customer_interests": {"Type": "String", "Value": "baseball"}
"customer_interests": {"Type": "String", "Value": "football"}

它还匹配以下消息属性(因为它包含的值不是 rugbytennis):

"customer_interests": {"Type": "String.Array", "Value": "[\"rugby\", \"baseball\"]"}

但是,它不匹配以下消息属性:

"customer_interests": {"Type": "String", "Value": "rugby"}

前缀匹配

当策略属性值包含关键字 prefix 时,它匹配以指定字符开头的任何消息属性值。

考虑以下策略属性:

"customer_interests": [{"prefix": "bas"}]

它匹配以下任一消息属性:

"customer_interests": {"Type": "String", "Value": "baseball"}
"customer_interests": {"Type": "String", "Value": "basketball"}

但是,它不匹配以下消息属性:

"customer_interests": {"Type": "String", "Value": "rugby"}

属性数值匹配

您可以使用数值来匹配消息属性和筛选消息。在 JSON 策略中,不会用双引号将字符串值引起来。您可以使用以下数值操作来匹配消息属性。

精确匹配(白名单)

当策略属性值包含 numeric 关键字和 = 运算符时,它将匹配具有相同名称和相同数值的任何消息属性。

考虑以下策略属性:

"price_usd": [{"numeric": ["=",301.5]}]

它匹配以下任一消息属性:

"price_usd": {"Type": "Number", "Value": 301.5}
"price_usd": {"Type": "Number", "Value": 3.015e2}

Anything-But 匹配(黑名单)

当策略属性值包含关键字 anything-but 时,它匹配 包含任一策略属性值的任何消息属性。

考虑以下策略属性:

"price": [{"anything-but": [100, 500]}]

它匹配以下任一消息属性:

"price": {"Type": "Number", "Value": 101}
"price": {"Type": "Number", "Value": 100.1}

它还匹配以下消息属性(因为它包含的值不是 100500):

"price": {"Type": "Number.Array", "Value": "[100, 50]"}

但是,它不匹配以下消息属性:

"price": {"Type": "Number", "Value": 100}

值范围匹配

除了 = 运算符之外,数值策略属性还可以包含以下运算符:<<=>>=

考虑以下策略属性:

"price_usd": [{"numeric": ["<", 0]}]

它匹配任何具有负数值的消息属性。

考虑另一个消息属性:

"price_usd": [{"numeric": [">", 0, "<=", 150]}]

它匹配任何具有正数(最大为 150)的消息属性。

属性键匹配

您可以使用 exists 运算符来检查传入消息中是否存在属性,其键与筛选策略中列出的键匹配。

考虑以下策略属性:

"store": [{"exists": true}]

它匹配至少包含 store 属性键的任意消息,如下所示:

"store": "fans" "customer_interests": ["baseball", "basketball"]

但是,它不匹配不含 store 属性键的任何消息,如下所示:

"customer_interests": ["baseball", "basketball"]

AND/OR 逻辑

您可以使用包含 AND/OR 逻辑的操作来匹配消息属性。

AND 逻辑

可使用多个属性名称来应用 AND 逻辑。

考虑以下策略:

{ "customer_interests": ["rugby"], "price_usd": [{"numeric": [">", 100]}] }

它匹配任何 customer_interests 值设置为 rugby price_usd 值设置为大于 100 的数字的消息属性。

OR 逻辑

通过将多个值分配给一个属性名称来应用 OR 逻辑。

考虑以下策略属性:

"customer_interests": ["rugby", "football", "baseball"]

它匹配任何 customer_interests 值设置为 rugbyfootball baseball 的消息属性。