amazon-sns - SNS过滤器可以与订阅同时应用吗?
问题描述
假设一个 AWS SNS 主题。此主题的消息具有字符串类型的 MessageAttribute“IsTestMessage”。
使用 AWS 控制台,我添加了一个新的电子邮件订阅者。他们会收到一封确认电子邮件。确认后,他们将收到有关此主题的所有消息,包括测试消息。这不是故意的。
我想在他们确认之前应用一个过滤器,IsTestMessage: "false"
例如让我说。
我可以在订阅创建时应用过滤器来避免这些不正确的交付吗?控制台中似乎没有办法这样做,但我愿意使用 CLI、SDK 等。
解决方案
通过 CLI,我一直遇到与@John Rotenstein 相同的错误:Error parsing parameter '--attributes': Expected: '=', received: '"'
无论我尝试了什么,它都没有接受它,所以我只能假设 sdk 的一部分被破坏了。
创建 SNS 主题、SQS 队列和添加订阅的完整 bash 示例:
# some params - SNS_ENDPOINT and SQS_ENDPOINT are for localstack - you probably don't need them
# in production
SQS_ENDPOINT="${SQS_ENDPOINT:-http://localhost:4566}"
SNS_ENDPOINT="${SNS_ENDPOINT:-http://localhost:4575}"
REGION=eu-west-1
# Create an SNS topic, "my-topic" and extract the ARN
MY_TOPIC_ARN=$(aws sns create-topic --name "my-topic" --endpoint-url=$SNS_ENDPOINT --region=$REGION --query TopicArn --output text)
# Create a SQS queue that will get messages from the SNS topic - extract the url
MY_QUEUE_URL=$(aws sqs create-queue --queue-name "my-queue" --endpoint-url=$SQS_ENDPOINT --region=$REGION --query QueueUrl --output text)
# Get the queue arn
MY_QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url "$MY_QUEUE_URL" --endpoint-url=$SQS_ENDPOINT --attribute-names QueueArn --query Attributes --output text)
# Subscribe our sqs queue to our sns topic - extract the subscription arn
MY_SUBSCRIPTION_ARN=$(aws sns subscribe --topic-arn $MY_TOPIC_ARN --protocol sqs --notification-endpoint $MY_QUEUE_ARN --endpoint-url=$SNS_ENDPOINT --region=$REGION --attributes RawMessageDelivery=true --query SubscriptionArn --output text)
# Add a filter policy
aws sns set-subscription-attributes --subscription-arn $MY_SUBSCRIPTION_ARN --attribute-name FilterPolicy --attribute-value "{\"someKey\":[\"someValue\"]}" --endpoint-url=$SQS_ENDPOINT --region=$REGION
注意:这不涉及设置死信队列(一个用于订阅本身,一个用于 SQS 队列,具体取决于您使用它做什么),也不是您需要允许的策略SNS 向 SQS 等发送消息
云的形成
https://docs.aws.amazon.com/sns/latest/dg/SendMessageToSQS.cloudformation.html给出了一个同时创建一个订阅主题的例子:
"Resources": {
"MySNSTopic": {
"Type": "AWS::SNS::Topic",
"Properties": {
"Subscription": [{
"Endpoint": {
"Fn::GetAtt": ["MyQueue1", "Arn"]
},
"Protocol": "sqs"
}]
}
},
...
}
我还没试过那个,所以我不能和它说话
无服务器
您也可以通过 Serverless 单独创建它们:
Resources:
MyTopic:
Type: "AWS::SNS::Topic"
Properties:
TopicName: ${self:custom.myTopicName}
MyTopicQueue:
Type: "AWS::SQS::Queue"
Properties:
QueueName: ${self:custom.myTopicQueueName}
VisibilityTimeout: 120
RedrivePolicy:
maxReceiveCount: 3
deadLetterTargetArn:
Fn::GetAtt:
- MyTopicQueueDeadLetter
- Arn
MyTopicQueueDeadLetter:
Type: "AWS::SQS::Queue"
Properties:
QueueName: ${self:custom.myTopicDeadQueueName}
# Policy to allow SNS to post to SQS
MyTopicQueuePolicy:
Type: AWS::SQS::QueuePolicy
Properties:
PolicyDocument:
Version: "2012-10-17"
Statement:
Effect: "Allow"
Principal:
Service: sns.amazonaws.com
Resource:
- !GetAtt
- MyTopicQueue
- Arn
- !GetAtt
- MyTopicQueueDeadLetter
- Arn
Action:
- sqs:*
Condition:
ArnEquals:
aws:SourceArn: !Ref MyTopic
Queues:
- Ref: MyTopicQueue
- Ref: MyTopicQueueDeadLetter
# Create the subscription for the SNS to SQS queue
MyTopicSnsToSqsSubscription:
Type: "AWS::SNS::Subscription"
Properties:
TopicArn: !Ref MyTopic
Endpoint: !GetAtt
- MyTopicQueue
- Arn
Protocol: sqs
RawMessageDelivery: 'true'
FilterPolicy:
type:
- 'playerLost'
RedrivePolicy:
deadLetterTargetArn: !GetAtt
- MyTopicQueueDeadLetter
- Arn
不过,我仍然不能 100% 确定该政策,就像在 AWS 控制台中一样,当我查看订阅时,它仍然说它没有权限发布到死信队列(这里我使用的是订阅和 SQS 主队列的相同死信队列),所以我显然遗漏了一些东西。
和CloudFormation类似,在声明主题的时候大概可以直接声明订阅,不过我没试过。
应该足以让你开始
推荐阅读
- c - 使用 snprintf 在 c 中连接给出分段错误
- asp.net-core - 从 Visual Studio 和 .NET Core 服务更新发布,最好的解决方法是什么?
- cron - 删除由 cronjob 创建的所有 k8s pod
- python - keras,模型(数据)是什么意思
- excel - Excel:考虑到一天,以 30 分钟的间隔计算总计划
- ajax - 初学者 - 使用 django 的数据表服务器端处理
- firebase - Firestore获取值不在数组中的文档?
- html - 如果我初始化选中,则无法选中或取消选中复选框
- angular - NgbModal 在 IE chrome 的顶部显示在其中心
- spring - Spring boot - 可执行的战争也可部署到应用服务器