亚马逊AWS官方博客

Amazon SES 实时日志实践指南

一、方案概述

对于企业而言,构建大规模电子邮件解决方案是一项非常具有挑战性、成本高昂且复杂的任务:您必须构建基础设施、配置网络、预热 IP 地址和保护发件人声誉。Amazon SES 轻松解决了这些挑战,让企业具备每年发送数千亿封电子邮件的能力。

本文将分享如何快速上手采用 Amazon SES 实现邮件发送,并重点介绍通过 Amazon OpenSearch 展示 Amazon SES 实时日志监控仪表盘;使用 Amazon SES 的日志功能,将日志数据导入 Amazon OpenSearch 集群中,并利用 OpenSearch 内置丰富的仪表盘以监控 SES 的邮件传递情况。

Amazon SES 实时监控包含以下指标:

  • Send(发送)– 发送请求成功,Amazon SES 将尝试将邮件发送到收件人的邮件服务器(如果使用账户级别或全局抑制,SES 仍会将其计为发送,但会抑制送达)。
  • Rendering Failure(呈现失败)– 由于模板呈现问题,未发送电子邮件。当模板数据丢失或模板参数与数据不匹配时,可能会发生此事件类型。
  • Reject(拒绝)– Amazon SES 已接受电子邮件,但确定它包含病毒,而未尝试将其发送到收件人的邮件服务器。
  • Delivery(送达)– Amazon SES 成功将电子邮件发送到收件人的邮件服务器。
  • Hard bounce(查无此人的邮件)– 收件人的邮件服务器永久拒绝了电子邮件(只有当 Amazon SES 重试一段时间后仍无法发送邮件时才包括软退回邮件)。
  • Complaint(投诉)– 电子邮件已成功送达收件人的邮件服务器,但收件人将其标记为垃圾邮件。
  • Delivery Delay(送达延迟)– 无法将电子邮件传送给收件人的邮件服务器,因为临时出现问题。例如,当收件人的收件箱已满,或者当接收电子邮件服务器遇到临时问题时,可能会发生传送延迟。
  • Subscription(订阅)– 电子邮件已成功发送,但收件人通过单击电子邮件标头中的 List-Unsubscribe 或脚注中的 Unsubscribe 链接更新了订阅首选项。
  • Open(打开)– 收件人已收到邮件并在其电子邮件客户端中打开了邮件。
  • Click(单击)– 收件人单击了电子邮件中包含的一个或多个链接。

注:您可以通过 Amazon SES API 提供的 GetSendStatistics 操作来获得回调信息以统计您的邮件状态和数据,详见官方文档

通过本方案部署仪表盘可以直接展示以上指标数据,用户可以实现:

  • 实时监控:管理员可以实时了解 Amazon SES 邮件传递的情况,识别问题并快速解决。
  • 可视化展示:通过 OpenSearch 创建的仪表盘,用户可以实现指标类型分类、日志事件过滤,数据呈现更加直观、清晰。
  • 可扩展性:使用 Amazon OpenSearch 集群,可以轻松地扩展集群规模,以适应不断增长的日志数据量。

二、方案架构

架构图流程说明:

  1. 日志导出:通过 Amazon SES 发送的所有邮件都会以 Message ID 为唯一值索引,发送事件(包括发送、送达、打开、点击、退回、投诉、拒绝、呈现失败和送达延迟等)默认都会以日志的文档存放起来;通过配置 SES 中的“Configuration Set”中的“Event Destination”为 Amazon Kinesis Data Firehose,使 SES 的日志将会自动发送到 Kinesis Firehose 目标。
  2. 日志处理:在 Kinesis Firehose 设置中,我们可以让日志按天进行轮询(Rotation),让日志更好的管理。
  3. 数据展示:通过 OpenSearch Dashboard 创建仪表盘,让业务人员和运维工程师实时掌握邮件的发送情况。
  4. 失败日志处理:对于存储失败的日志(较小概率),可以设置自动存储于 S3中。

三、部署指南

3.1 环境准备

3.1.1 SES 移出沙盒

Amazon SES 沙盒是供新用户小范围测试 Amazon SES 功能的隔离区域。当您的账户处于沙盒中时,您只能将电子邮件发送到已验证身份。经验证身份是您已证明您拥有的电子邮件地址或域。另外,当您的账户在沙盒中时,您每天可发送的电子邮件数量和您每秒可发送的邮件数量都存在限制。因此,如果我们计划将 Amazon SES 用于生产环境前,需要先完成移出沙盒的操作流程。

打开SES “Account dashboard”,点击“Request Production Access” 申请移出沙盒。

按照说明完成表单的填写后,SES 会自动帮您创建一个“SES: Production Access” 的工单。

待 Case 工单 Resolved 后,您的帐号会被移出沙盒,您可以按需提高“Daily sending quota” 和 “Maximum send rate”。

3.1.2 验证用于发邮件的 Identity

打开 SES 的“Verified identities”, 点击“create identity”创建用于发邮件的 Identity。

选择“Domain”域名的验证方式,并输入你想要验证的域名。

窗口往下拉后,展开“Advanced DKIM settings”, 选择“Easy DKIM”, “RSA_2048_BIT”的 DKIM 签名密钥长度,其它保持默认,然后点击“Create Identity”。

Identity 创建成功后,窗口会自动跳转到该 Identity,在“Authentication”标签页中,可以看到具体需要在您的域名中要配置的 DKIM 值去验证您是该域名的所有者。

登陆你的域名供应商控制台,配置相应的三个 DKIM CNAME(3 个都需要配置才能验证)。

注意:上图的 Name 列是包含了域名本身的,在 DNS 配置中,通常需要去掉。如 Name 值为【tthk76asq3c4u5hdbapipwywcuq75z7c._domainkey.email.domain.com】,应该只需要设置“主机记录”为 【tthk76asq3c4u5hdbapipwywcuq75z7c._domainkey.email】。


大约 10 分钟后,我们可以看到域名已经验证成功,建议发送测试邮件验证 Identity的配置。

3.1.3 创建 Amazon OpenSearch Service

登录 Amazon Web Services 控制台,选择 OpenSearch Service,选择 Create a new domain(创建新域)。

输入 OpenSearch 集群的名字,如“ses-log-lab”。

选择 Production(生产环境,并选择 OpenSearch 2.5 版本(推荐使用最新版本)。

Data nodes(数字节点),选择多 AZ 部署,并推荐使用 6 代 ARM 的节点,并使用 gp3 的 EBS (本次 Blog 使用 r6g.xlarge, 2 个节点;在生产环境,需按需选择)。

下拉屏幕至“Dedicated master nodes”(专用主节点),生产环境最好使用 3 台 r6g.large 作为 dedicated master 保证横向扩展过程高可用性(对于测试环境,为了控制成本,也可以先不启用专用主节点)。

下拉屏幕至“Network”(网络),选择 Public access(公网访问),并在 Fine-grained access control(精细化权限管理)中设置 master 用户的用户名和密码(注意:生产环境可能会设置在 VPC access,并使用 IAM ARN 进行授权)。

其它保持默认,并选择 Create(创建。待创建成功,可以登陆 Opensearch Console,打开集成的 dashboard 确认权限和功能。

3.1.4 创建 Firehose Delivery Stream

打开 Kinesis Data Firehose 控制台。您可以在 Amazon Web Services 控制台顶部的服务搜索框中键入 firehose 以查找链接或单击 Firehose Console

点击右上角的“Create delivery stream”。

选择 “Direct PUT” 作为源(Source),目标(Destination)选择“Amazon OpenSearch Server”,并为该流(Stream)设定名字“PUT-OPS-ses”。

选择已经创建好的 OpenSearch 集群“ses-log-lab”, 并配置 index 的名字。建议设置 Index Rotation 为每天(Every Day),以便于日志的管理。

展开“Buffer Hints”, 变更“Buffer interval”的值为 60 秒,以便让日志更快的存储到 OpenSearch 上面。

向下滚动到备份设置(Backup Settings),单击 S3 备份桶下的浏览(Browse),选择其一个已经创建的 S3 桶,用来存放日志,并在 prefix 中,输入 seslog 作为 S3 备份存储桶前缀。将其余值保留为默认值,向下滚动到页面底部,然后单击“Create delivery Stream” 创建流。

Firehose 的流将在一分钟左右创建完成,您将在控制台中看到该流为“Active”的状态。

点击进入已经创建的“PUT-OPS-ses”流,点击 Configuration(配置)标签。

下拉屏幕至“Service access”(服务访问),点击里面的 IAM Role,默认会在一个新的浏览器标签页面打开。

在角色的 ARN 中单击“复制”小按钮将 ARN 复制到剪贴板。将此角色 ARN 保存在某个位置,它将在接下来的步骤中使用。

 3.1.5 配置 firehose 写日志到 OpenSearch 的 Fine Grained 权限

为了防止未经授权访问您的 OpenSearch 集群,我们创建了细粒度访问控制。要使 Firehose 能够向 OpenSearch 集群发送数据,我们必须通过在 OpenSearch 中配置角色和权限来授予 Firehose 对集群的访问权限。

打开上一小节创建的 Opensearch 集群控制台,获取 Opensearch Dashboard 的网址。

打开 dashboard 网页,并输入之前设置的用户名和密码。

单击左上角的菜单按钮(汉堡菜单),然后选择 OpenSearch 插件下的安全菜单。

为了生产最小权限原则,在 OpenSearch 中创建专属的 Role 给 Firehose 用,如果仅用于测试可直接使用已经创建好的“all_access” Role(admin 权限)。

点击 Role,并点击“Create Role”创建新的角色。

输入 Role 的名字:“firehose-role”, 对于“群集 Cluster”权限,请添加Cluster_composite_ops 和 Cluster_monitor。请确保您选择了 cluster_composite_ops,而不是非常相似的 cluster_composit_ops_ro。

在“Index permissions”(索引权限)下,如果未展开“添加索引权限”,请展开该权限。输入“seslog*”作为“索引”(测试环境为了方便使用,可以直接用“*”代替)。这是我们之前在配置 Firehose 时输入的目标索引的名称。在“权限”下,添加三个操作组:crud、create_index 和 manage。

将其余部分保留为默认值,向下滚动到页面底部,然后单击“创建”。

创建角色后,单击页面顶部的 Mapped users(映射用户)。点击“Map Users”(映射用户),在“后端角色”下,输入您在上一节末尾复制的 Firehose Delivery 角色的 IAM ARN。单击 Map 将映射添加到 OpenSearch。

3.2 Amazon SES Configuration Set 配置

3.2.1 创建一个 IAM Role 给 SES 服务去 PUT 日志到 Firehose 流中,可参考文档做最小权限设置,Blog 将为其开放 Firehose Full Access

打开 IAM 服务,选择 Role,并选择 Create Role 创建角色。


选择“Trusted entity type” 为“Custom Trust policy”,并在编辑器中输入允许 SES 服务对该 Role 进行 AssumeRole 动作,并选择 Next 下一步。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": {
        "Service": "ses.amazonaws.com"
      },
            "Action": "sts:AssumeRole"
        }
    ]
}

选择“AmazonKinesisFullAccess” 权限,并选择 Next 下一步。

输入 IAM Role 的名字“firehose-for-ses-log”,和 Description “Allow SES to assume this role to put data to firehose.”, 并选择“Create Role” 创建。

查看 Role 的情况:

3.2.2 配置 SES Configuration Set 设置日志目标

打开 SES 服务,选择左侧菜单栏中的“Configuration Sets”(配置组),选择“Create Set”。


设置 Configuration Set 的名字“shareIpPool-firehose-opensearch”,选择使用 default 的 Share IP Pool 发邮件。

注意:可按需选择在“Tracking Options”中,启动使用一个特定的重定向网址,去记录 Open 和 Click 的活动。对于邮件中包含超链接,会在超链接前加自定义重定向域名,此设置需要客户网站程序自动重定向的功能,测试环境中无需打开。

其它保持默认配置,点击创建成功后会直接进入该 Set 进行配置。

选择“Event destinations”(事件目标),选择“Add destination”(增加目标)。


点选收集所有的 Event 事件,并点击“Next”。

选择“Amazon Kinesis Data Firehose”的目标类型,命名该目标为“firehose-to-es”, 并选中 Event publishing 为“Enabled”。

选择刚才创建的 Firehose 流的名字“PUT-OPS-ses”, 并为其指定的 IAM Role “firehose-for-ses-log”,并点击下一步“Next”。

创建完成显示如下:

3.2.3 为 Identity 域名配置默认的 Configuration Set

通过配置默认的 Configuration Set,邮件发送将会自己使用该 Set 配置好的 IP 池(共享/专享)和并将日志自动收集到配置好的事件目标中。

3.3 OpenSearch Dashboard 展示日志配置

3.3.1 创建 OpenSearch Dashboard  template

打开 dashboard 中的 Dev Tools。

在 console 中输入以下代码创建 document template,设置 index 的 shard 和 replica 的数量,然后点击运行(注意:当前模板是使用 2 个 shards,1 份 replica。生产环境一定要开启至少一份 replica,以保证数据节点出现故障时 ES 可以自动恢复,而不需要重建索引导致数据丟失)

PUT  _template/awswaf-logs
{
    "index_patterns": ["seslog*"],
    "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1
    }
}

创建完成后会返回 “acknowledged” : true

3.3.2 导入已经创建好的 Index Pattern,Visualize 和 Dashboard

我们可以根据用户的需求,轻松用 OpenSearch 构建日志分析的 Dashboard。为了方便使用和快速上手,您也可以使用如下 Amazon Web Services 企业级支持团队构建的 SES log Dashboard。

打开 GitHub 链接,选择 “Code → Download ZIP ” 下载索引模式(Index Pattern),展示模板(Visualize)和仪表盘模板(Dashboard)。

在“Management”中选择“Stack Management”.

在“Saved Objects”页面,点击“Import”。

选择在 GitHub 下载的 ndjson 文件,选择“import” 并点“Done”完成导入查看对像情况。

3.3.3 使用 SES 控制台或者 API 发送测试邮件

进入之前在 SES 所配置好的 Identity,选择“Send test email”。

选择“formatted”的方式,输入发件邮箱的名字,在 Scenario 中选择“Custom”, 输入收件邮箱,输入邮件标题 Subject,输入邮件正文 Body,并选择之前创建的 Configuration Set “shareIpPool-firehose-opensearch”,然后点击“Send Test Email”。

此外,可以在 Scenario 中选择其它场景进行模拟发送邮件,如 bounce,complain,automatic response 等场景。

另外客户也可以使用 SES API,如最简单的 Amazon Web Services CLI 的方式批量发送邮件,样例如下:

目标收件人文件名 destination.json

{
"ToAddresses":  ["recipient1@example.com", "recipient2@example.com"],
"CcAddresses":  ["recipient3@example.com"],
"BccAddresses": []
}

邮件正文的文件名:message.json

{
   "Subject": {
       "Data": "Test email sent using the AWS CLI",
       "Charset": "UTF-8"
   },
   "Body": {
       "Text": {
           "Data": "This is the message body in text format.",
           "Charset": "UTF-8"
       },
       "Html": {
           "Data": "This message body contains HTML formatting. It can, for example, contain links like this one: <a class=\"ulink\" href=\"http://docs.thinkwithwp.com/ses/latest/DeveloperGuide\" target=\"_blank\">Amazon SES Developer Guide</a>.",
           "Charset": "UTF-8"
       }
   }
}

执行结果:

test@environemnt % aws ses send-email --from jason@email.example.com --destination file://destination.json --message file://message.json
{
    "MessageId": "01000186ee712cd6-495edead-48b5-4967-93d9-698d7e7b6dc6-000000"
}
test@environemnt % 

待测试邮件发送完,等待约 60s 时间,可以打开 Dashboard 查看邮件的发送情况了。

3.3.4 使用 Dashboard 监控邮件发送的实时情况

如“方案概述”章节所介绍,通过查看 SES Dashboard,我们可以非常容易地分析应用地邮件的发送情况,非常直观地看到需要处理的 Bounce,Complaint,并可以很方便地对其进行分析和处理。

四、总结

本文通过 Amazon SES 的日志功能将日志数据导入 Amazon OpenSearch 集群,并利用 OpenSearch 内置的仪表盘监控 SES 邮件传递情况。分析 Amazon SES 日志数据可获得有关邮件发送和活动推广情况的信息,有助于有针对性地调整发送策略,提高业务效益。类似的方法也可用于分析 WAF、ALB、EKS 等日志数据,实现统一的日志管理。

本篇作者

谢志鹏

亚马逊云科技技术客户经理,负责企业级客户的架构设计、成本优化和技术支持等工作,在亚马逊云科技支持多个知名游戏公司在全球的项目发行工作;拥有十年以上 IT 架构、运维经验,在云安全、应用微服务化架构等方面拥有丰富的实战经验。

高旭龙

亚马逊云科技解决方案架构师,拥有十年以上 IT 领域从业经历,专注于数字原生企业的云架构设计和咨询,在亚马逊云科技支持多个知名游戏公司在全球的项目发行工作;在全球云网络构建、网络优化加速、应用交付、应用层安全、网络安全、CDN 等方面有丰富的实战经验。