构建电子邮件归档系统:存储电子邮件正文
电子邮件
·
2019年3月4日

关键要点
目的: 本文概述了使用 SparkPost、Amazon S3 和 MySQL 构建电子邮件存档系统的第一阶段。它解释了如何复制、捕获和存储电子邮件以实现长期访问和合规性。
核心理念: 系统自动将原始邮件正文(rfc822 格式)存储在 S3 中,并将元数据(主题、发件人、时间戳等)记录到 MySQL 中,以实现快速搜索和检索。
涵盖要点:
创建存档副本: 使用 SparkPost 的 Archive feature 向指定存档地址发送外发邮件的相同副本,确保正文和追踪链接保持相同。
通过 UID 进行数据绑定: 将唯一标识符 (UID) 嵌入到邮件正文和 X-MSYS-API 元数据中,以链接原始和存档消息。
入站处理: 在 SparkPost 中配置入站域和 webhook,通过应用程序采集器接收存档邮件的 JSON 负载。
在 S3 中存储电子邮件: 将解析后的 rfc822 正文上传到 S3 存储桶,使用生命周期规则(例如一年后转换到 Glacier)降低存储成本。
在 MySQL 中记录元数据: 保存关键字段,例如 RCPT_TO、FROM、SUBJECT 和 S3 文件名,以用于搜索索引和将来检索。
性能考虑: 高效的代码和最小的日志记录确保采集器能够以最小的延迟每分钟处理数百个请求。
大局观: 这个基础支持未来的增强——比如日志事件存储、故障警报和 UI 可视化——为可扩展、可审计的电子邮件存档解决方案奠定基础。
Q&A 精华
这个项目的目标是什么?
创建一个自动化电子邮件存档系统,将消息正文存储在Amazon S3中,同时在MySQL数据库中维护可搜索的元数据。
为什么使用 SparkPost 的 Archive 功能?
它允许您生成外发邮件的精确副本,保留其结构和跟踪数据以进行合规和审查。
每封存档电子邮件如何链接到其原始消息?
一个唯一的UID嵌入到电子邮件正文和元数据中,使原始副本和归档副本之间的准确交叉引用成为可能。
为什么使用S3进行存储?
S3 提供可扩展的存储和生命周期管理选项(如 Glacier),使得长期电子邮件保留变得具有成本效益。
MySQL数据库存储什么?
它存储可搜索的元数据字段—如subject line、sender、timestamps和S3 filename—允许高效的查询和检索。
接下来的开发步骤是什么?
添加日志事件追踪、自动错误报告、简化的收集器,以及用于查看或重新发送归档电子邮件的用户界面。
在这篇博文中,我将描述我如何将电子邮件的正文存储到S3(亚马逊的Simple Store Service)以及辅助数据存储到MySQL表中,以便于交叉引用。最终,这将是代码库的起点,该代码库将包括一个应用程序,允许轻松搜索存档的邮件,然后显示这些邮件以及事件(日志)数据。这个项目的代码可以在以下GitHub代码库中找到:https://github.com/jeff-goldstein/PHPArchivePlatform。
虽然我将在这个项目中利用S3和MySQL,但绝不是仅有的可以用于构建存档平台的技术,鉴于它们的普及性,我认为它们是这个项目的不错选择。在一个全规模高容量系统中,我会使用比MySQL性能更高的数据库,但对于这个示例项目,MySQL非常合适。对于考虑选择PostgreSQL作为存档数据库的组织,实施适当的备份和还原程序对于维护生产系统中的数据完整性是至关重要的。
在这个项目的第一阶段中,我详细介绍了我采取的步骤:
创建用于存档的重复电子邮件
使用SparkPost的Archiving和Inbound Relay功能,将原始电子邮件的副本发送回SparkPost进行处理,转换为JSON结构,然后发送到webhook收集器(应用程序)
拆解JSON结构以获取必要的组件
将电子邮件正文发送到S3进行存储
在MySQL中为每封电子邮件记录一个条目以供交叉引用
创建邮件的副本
获取 Archive 版本
为了获取一份电子邮件的存档副本,您需要采取以下步骤:
创建一个子域,您将把所有存档(重复)的电子邮件发送到该子域
设置适当的DNS记录,将所有发送到该子域的电子邮件转发到SparkPost
在SparkPost中创建一个入站域
在SparkPost中创建一个入站Webhook
创建一个应用程序(收集器)来接收SparkPost的Webhook数据流
可以使用以下两个链接来帮助您指导此过程:
SparkPost技术文档:启用入站电子邮件中继和中继Webhooks
另外,我去年写的博客,存档电子邮件:跟踪已发送邮件的指南,将引导您通过SparkPost创建入站中继
* 注意:截至2018年10月,存档功能仅在使用SMTP连接到SparkPost发送电子邮件时有效,RESTful API不支持此功能。这可能不是问题,因为需要此级别审计控制的大多数电子邮件往往是由后端应用程序完全构建的个性化电子邮件,在需要发送之前。
在JSON结构中获取重复的电子邮件
将重复的电子邮件存储在 S3 中
在 MySQL 中存储 Meta Data
我们在以前的步骤中获取了所有必要的数据,所以存储的步骤很简单。 在这个第一阶段,我选择建立一个包含以下字段的表:
MySQL Metadata Fields
Field | Purpose |
Date/time (auto) | 记录该条目时的时间戳 |
RCPT_TO address | 存档消息的目标电子邮件地址 |
DATE header timestamp | 原始电子邮件的发送时间 |
SUBJECT header | 用于索引和搜索的主题行 |
FROM header | 用于查找的发件人标识符 |
S3 directory | S3 存储桶中的目录路径 |
S3 filename | 存储在 S3 中的唯一 .eml 文件 |
在 upload.php 应用程序文件中名为 MySQLLog 的函数经历了必要的步骤以打开 MySQL 的链接,插入新行,测试结果并关闭链接。为了更好的考虑,我确实添加了另外一步,那就是将这些数据记录到文本文件中。我是否需要进行更多的错误日志记录?是的。但我确实希望保持这段代码的简洁,以便让它运行得非常快。有时这段代码会每分钟调用数百次,需要尽可能高效。在未来的更新中,我将添加辅助代码来处理失败并将这些失败通过电子邮件发送给管理员进行监控。
总结
在几个相当简单的步骤中,我们能够通过建立一个强大的电子邮件归档系统的第一阶段,将电子邮件副本存储在S3中,并在MySQL表中进行数据交叉引用。这将为项目的其余部分奠定基础,未来几个帖子中将继续讨论。
在此项目的未来修订中,我预计会:
存储所有原始电子邮件的日志事件
在上传或记录失败时,将存储错误发送给管理员
简化收集器的复杂性。
添加一个用于查看所有数据的UI
支持重新发送电子邮件的功能
与此同时,我希望这个项目对您有趣且有帮助;祝发送愉快。



