我的系统使用 sendmail 从 php 发送电子邮件。我发现 stack exchange 上有几十个关于从 sendmail/php 发送电子邮件延迟的问题。我已全部阅读,但仍然无法解决我的问题。
我有一台生产服务器和一台开发服务器。生产服务器位于数据中心,使用“智能主机”来中继电子邮件,直接发送电子邮件会被防火墙阻止。开发服务器位于我们的办公室,直接发送电子邮件。它们还使用不同的 DNS 服务器。除此之外,这些服务器尽可能地相似。我的系统需要一次发送很多封电子邮件(大约 10,000 封)。我的开发服务器能够在一小时内发送所有电子邮件。生产系统需要超过 24 小时。电子邮件大小为 2kb-5kb。
在我的生产服务器上:
我已确定从 php 到 sendmail 的传递速度很快。Sendmail 在向某些域发送电子邮件时速度很慢。大型电子邮件服务(gmail、aol、yahoo)速度很快。我曾尝试向仅 aol 地址发送 1000 封电子邮件,它们都在几分钟内发送完毕,因此我知道中继能够快速发送电子邮件。我的问题是,我的地址列表中的大多数电子邮件地址都是小型域,而这些地址中的大多数都很慢。这使我相信缓慢的步骤涉及 DNS。以下是我的邮件日志文件的摘录({花括号} 中的值已替换以保护隐私)。
Mar 28 11:21:47 {servernamereplaced} sendmail[26242]: v2SILe8w026242: to={[email protected]}, ctladdr={[email protected]} (48/48), delay=00:00:07, xdelay=00:00:00, mailer=relay, pri=32561, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2SILlIu026244 Message accepted for delivery)
Mar 28 11:22:08 {servernamereplaced} sendmail[26247]: v2SILmT8026247: to={[email protected]}, ctladdr={[email protected]} (48/48), delay=00:00:20, xdelay=00:00:10, mailer=relay, pri=32550, relay=[127.0.0.1] [127.0.0.1], dsn=2.0.0, stat=Sent (v2SILwOh026248 Message accepted for delivery).
您可以看到这些延迟很长。但是,当我运行时,host -t mx domain1replaced.net
我很快就能得到结果(不到半秒,与 gmail.com 或 aol.com 一样长)。
我看到一些答案提到了 sendmail.cf 中的超时值,但是我对该文件了解不够多,无法自己处理。此外,延迟值并不完全相同或为同一数字的倍数。它们似乎相当分散在 5 到 30 秒之间。让我感到困惑的是,我的开发服务器发送它们的速度非常快,但我无法让我的生产服务器做同样的事情。我该怎么做才能加快我的生产服务器的速度?
答案1
让我们开始分析 sendmail 的日志,特别delay
是 和xdelay
。从这里:
延迟:总邮件延迟:接收与最终投递或退回之间的时间差)。格式为 delay=HH:MM::SS(延迟少于一天),否则为 delay=days+HH:MM::SS
xdelay:消息在最终交付过程中传输所需的总时间。这与 delay= 等式不同,因为 xdelay= 等式仅计算实际最终交付中的时间。
为了更好地强调delay/xdelay之间的区别(取自这里):
这与 delay= 不同,delay= 显示邮件所花费的总时间,从最初收到或排队邮件(可能是几天前)开始计算,直到最终送达。对于 SMTP 邮件,xdelay=计算在 sendmail 开始尝试连接远程主机时开始。
您的日志显示以下延迟/xdelay:
delay=00:00:07, xdelay=00:00:00
:此邮件在 sendmail 队列中等待了 7 秒在 smtp 传输被处理之前。这是服务器过载的迹象,而不是连接/DNS问题:毕竟,实际的传输几乎是立即执行的;
delay=00:00:20, xdelay=00:00:10
:此时,邮件在 sendmail 队列中停留了 10 秒,实际传输工具又停留了 10 秒。根据您服务器的信誉,这可能是一个非常合理的值:许多邮件服务器会将 HELO/EHLO 延迟 5-30 秒,以防未知的中立发件人。
那么,为什么测试机比生产机快这么多呢?以下是一些可能性:
- 通过智能主机发送比直接发送电子邮件更简单、更快捷。从开发服务器发送时,您确定电子邮件是实际收到大约一个小时,或者这只是您的开发服务器将所有邮件传递到智能主机所需的时间?
- 也许您的智能主机享有良好的声誉并且远程服务器可以接收邮件而无需强制人为等待;
- 发送大量电子邮件是一项非常
fsync()
繁重的工作。您的开发和生产服务器是否真的相同,硬件和软件范围?智能主机的硬件和软件堆栈怎么样?
答案2
我假设如果你向之前速度很慢的地址发送另一封电子邮件,第二次发送时速度仍然会很慢。如果是这样,我会尝试在你的邮件服务器上使用 telnet 连接到远程邮件服务器,并以此方式发送测试电子邮件。我过去用这种方法解决了一些与延迟相关的问题。它有时可以帮助查明通信过程中的哪个步骤阻碍了事情的发展。
关于使用 telnet 发送邮件的详细论述:
https://weblogs.asp.net/owscott/Troubleshooting-email_2C00_-the-Telnet-way
答案3
问题可能不在于您在本地执行 DNS 查询,而在于远程端。当您的 SMTP 服务器 A 发送到 SMTP 服务器 B 时,服务器 B 将(可能)对 A IP 地址执行 PTR 查询,然后对返回的名称执行正向查询以确保它们匹配。如果这些 DNS 查询中的任何一个很慢,这可能解释了您的观察结果。
答案4
由于连接重用,向 100 个域发送电子邮件总是比向单个域中的 100 个用户发送电子邮件慢(postfix 会记录使用的连接数)预热 IP 和优化每个域的发送速率需要大量工作。如果将 tls 添加到组合中,您还会失去连接重用选项,因为每封电子邮件都会建立连接(tcp+tls 构建加上收件人速率限制)
如果您没有或不想花时间建立声誉和调整速率限制,您应该评估第三方选项。