目前,我一直在使用 PHP 和 Zend 框架通过 SMTP 和 GMail 的 SMTP 服务器发送电子邮件。那是因为我有一个 Google Apps 域设置来处理我的所有电子邮件,所以看起来我的电子邮件来自 mailer@mycompany.com。
现在,当用户注册或执行需要我的 Web 服务器向他们发送电子邮件的操作时,PHP 端可能需要 5 秒左右来启动 SMTP 连接并将电子邮件发送给他们。该过程将是这样的:
- 用户填写注册表
- 用户提交表单
- PHP 脚本将信息保存到数据库并向他们发送电子邮件(5-10 秒)
- 用户重定向到另一个页面
现在,当他们刚刚提交表单时,我的网络服务器不会有很大的延迟,而用户在那里坐了 10 秒钟,看起来好像正在加载。基本上,发送电子邮件过程是单线程的,因此服务器在完成发送电子邮件之前不能做任何其他事情,这在 5-10 秒之间,如果电子邮件地址有错误,有时需要 20 秒,所以这太长了。
人们通常如何解决这样的问题?
最初我尝试了一些事情:
使用另一个库,如 SwiftMailer。还是一样的问题。我认为这是 SMTP/TLS 握手需要额外的时间。
将电子邮件数据存储在数据库中,然后使用 fsockopen 向另一个页面发起异步请求,然后该页面将从数据库中获取电子邮件数据并发送电子邮件。同时,我的 PHP 脚本可以同步继续,用户会在表单提交后立即被重定向到下一页。问题是无法确认电子邮件是否已发送,或者是否失败。我想我可以在数据库表上设置一个标志,但我想向用户提供他们的电子邮件已发送的即时反馈。这意味着在下一页上,10 秒后向另一个页面发出 Ajax 请求,该页面将检查数据库表上的标志以查看它是否已发送,然后在页面上向用户显示响应。如果他们输入错误的电子邮件并且无法发送电子邮件,这将不起作用,
我想出的另一个选择是将电子邮件数据放在 $_SESSION 数组中,因此在提交页面并且用户位于重定向页面后,它会将 ajax 请求发送到另一个页面,该页面将获取会话数据并发送电子邮件,然后将回复发送回用户所在的页面,并告诉他们电子邮件已发送。这工作得很好,但我觉得这可能不是最好的方法。
所以我想知道最好的做法是什么?GMail 对于这种事情是否太慢了,因为它必须进行 TLS 握手?我是否应该将所有电子邮件排队到数据库中并每隔几分钟运行一次 CRON 作业以将它们发送出去,然后在发送后将它们从数据库中删除?问题是没有立即向用户提供他们的电子邮件发送正确的反馈。还是我不需要为此烦恼?他们要么收到电子邮件,要么没有。