Amazon Simple Notification Service (Amazon SNS) 是一项 Web 服务,用于协调和管理向订阅终端节点或客户端交付或发送消息的过程。订阅者(即 Web 服务器、电子邮件地址、Amazon SQS 队列、AWS Lambda 函数)在其订阅主题后通过受支持协议(即 Amazon SQS、HTTP/S、电子邮件、SMS、Lambda)之一使用或接收消息或通知。
使用场景
应用程序和系统警报时由预定义阈值触发的
通知推送电子邮件和文本消息
移动推送通知
通知推送电子邮件和文本消息
移动推送通知
架构
主题Topic
Amazon SNS 主题是一个逻辑访问点,可以充当通信通道。利用主题,您可以对多个终端节点(例如,AWS Lambda、Amazon SQS、HTTP/S 或电子邮件地址)进行分组。
Fanout
当 Amazon SNS 消息发送至主题且被复制和推送到多个 Amazon SQS 队列、HTTP 终端节点或电子邮件地址时,会出现“四散传播”场景。这允许进行并行异步处理。
观察着模式(我的观点)。
由使用场景可以知道,SNS的接受者种类有限。以邮件为例,信息广播后,就会立刻收到邮件,所以SNS主要功能是通知,并没有暂存信息的功能。所以很多时候与SQS连用,SQS提供存储空间。
111122223333为publisher的aws账号id,而Resource为subscriber账号的SNS topic的arn.
最佳实践
Baseline: Lambda1 -> SNS -> Lambda2 -> RDS (SNS可用于跨账号,SNS的拥有者为subscriber,因为需要setup filter policy,而SNS access policy只要指明publisher的AWS account id即可)111122223333为publisher的aws账号id,而Resource为subscriber账号的SNS topic的arn.
{
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:111122223333:root"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-west-2:444455556666:MyTopic"
}]
}
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam:111122223333:root"
},
"Action": "sns:Publish",
"Resource": "arn:aws:sns:us-west-2:444455556666:MyTopic"
}]
}
Filter policy用SNSMessageAttributes来实现,实质上是一个Map。Filter时候用
{
"Type": ["Feature"]
}
SNS->Lambda
SQS->SNS->SQS client
Amazon SNS 让应用程序通过“推送”机制将紧急消息发送给多个订阅者,并且无需定期检查
或“轮询”更新。
Amazon SQS 是分布式应用程序用于通过轮询模式来交换消息的消息队列服务,可用于分离
各个组成
部分的发送和接收而不要求所有组成部分都同时可用。
Amazon SNS 当前与 Amazon SQS FIFO 队列不兼容。
SNS->HTTP(S)
SNS->push on phone, 适用于 iOS 和 Mac OS X 的 Apple Push Notification Service (APNS)
SNS->SMS on phone
SNS->Lambda
SQS->SNS->SQS client
Amazon SNS 让应用程序通过“推送”机制将紧急消息发送给多个订阅者,并且无需定期检查
或“轮询”更新。
Amazon SQS 是分布式应用程序用于通过轮询模式来交换消息的消息队列服务,可用于分离
各个组成
部分的发送和接收而不要求所有组成部分都同时可用。
Amazon SNS 当前与 Amazon SQS FIFO 队列不兼容。
SNS->HTTP(S)
SNS->push on phone, 适用于 iOS 和 Mac OS X 的 Apple Push Notification Service (APNS)
SNS->SMS on phone
底层API
final SubscribeRequest subscribeRequest = new SubscribeRequest(topicArn, "email",
"name@example.com");
"name@example.com");
snsClient.subscribe(subscribeRequest);
final String msg = "If you receive this message, publishing a message to an Amazon SNS topic works.";
final PublishRequest publishRequest = new PublishRequest(topicArn, msg);
final PublishResult publishResponse = snsClient.publish(publishRequest);
接收通知没有API,一般以HTTP endpoint,邮件等方式接收。下面例子为HTTP endpoint (Java servlet)
Scanner scan = new Scanner(request.getInputStream());
StringBuilder builder = new StringBuilder();
while (scan.hasNextLine()) {
builder.append(scan.nextLine());
Message msg = readMessageFromJson(builder.toString());
功能
消息筛选
主题订阅者仅接收一部分消息,订阅者必须定义筛选策略。当您将一条消息发布到某个主题时,Amazon SNS 会比较该消息属性与该主题的每个订阅的筛选策略中的属性。如果任何属性匹配,Amazon SNS 会将消息发送给订阅者。否则,Amazon SNS 会跳过订阅者而不向其发送消息。如果某个订阅没有筛选策略,则该订阅将接收发布到其主题的每条消息。
向不同账户中的 Amazon SQS 队列发送 Amazon SNS 消息。
通过将 HTTP/S 终端节点作为订阅者
您可以使用 Amazon SNS 向一个或多个 HTTP 或 HTTPS 终端节点发送通知消息。为终端节点订阅主题时,您可以向主题发布通知,Amazon SNS 将发送 HTTP POST 请求,向已订阅终端节点传递通知内容。
主题订阅者仅接收一部分消息,订阅者必须定义筛选策略。当您将一条消息发布到某个主题时,Amazon SNS 会比较该消息属性与该主题的每个订阅的筛选策略中的属性。如果任何属性匹配,Amazon SNS 会将消息发送给订阅者。否则,Amazon SNS 会跳过订阅者而不向其发送消息。如果某个订阅没有筛选策略,则该订阅将接收发布到其主题的每条消息。
向不同账户中的 Amazon SQS 队列发送 Amazon SNS 消息。
通过将 HTTP/S 终端节点作为订阅者
您可以使用 Amazon SNS 向一个或多个 HTTP 或 HTTPS 终端节点发送通知消息。为终端节点订阅主题时,您可以向主题发布通知,Amazon SNS 将发送 HTTP POST 请求,向已订阅终端节点传递通知内容。
与Kafka比较
Amazon自主开发的一套发布者-订阅者系统,类似于Apache Kafka。用于股票实时统计,用户消息通知(LinkedIn),游戏中交易通知或预警。多个内容发布者利用语音助手发布自己的事件,语音助手视频组只订阅视频内容提供者。Topic是内容发布者的内容id,Kafka均衡负载地将不同Topic发布给相应订阅者。Kafka还要把内容持久化到系统本地,然后保留一段时间后删除。而订阅者是否阅读某topic就由订阅者系统自己维护,Kafka不负责事件状态。
Ref
官网