批量邮寄性能发送方式
Bulk Mailing Performance Sending Method
我写了一个邮件脚本 phpmailer/swiftmail 支持。实际上,小型活动效果很好,所有邮件都能到达收件人,没有垃圾邮件或服务器资源问题。
我对每个连接的发送性能有疑问。哪种方式更适合发送操作? (订阅者特定的不同邮件正文)
第一个场景;
- 打开时事通讯数据
- 在任务列表中捕获 100 个订阅者
- 为每个订阅者替换新闻稿 Data/Header 并保存到新数组
- 调用 PhpMailer - 通用 SMTP 连接设置
$mail->SMTPKeepAlive = true;
foreach($newArray as $k=>$v){
$mail->AddAddress($k, $v['name']);
$mail->Subject = $v['subject'];
$mail->Body = $v['content'];
$mail->Send();
}
$mail->smtpClose();
第二种情况(我的脚本中的当前方法,我已将 phpmailer class 调用到记录循环中);
- 打开时事通讯数据
- 打开任务列表 100 条记录
while($rs = $sql->fetch_assoc()){
Replace Newsletter Data/Header
Call PhpMailer - Common SMTP Connection settings
$mail->SMTPKeepAlive = true;
$mail->AddAddress($rs['mail'], $rs['name']);
$mail->Subject = $campRs['subject'];
$mail->Body = $campRs['content'];
$mail->Send();
}
$mail->smtpClose();
我对此感到困惑,如果我使用大量邮件列表,可能会出现服务器或脚本问题吗?
此致!
发送电子邮件所花的绝大部分时间是您的网络服务器和与之通信的 SMTP 服务器之间的 SMTP 通信。
这两种情况的速度可能相当快。
如果您需要提高性能,请考虑让多个线程同时发送到不同的电子邮件地址。
从 PHPMailer 发送的最快方法是通过 SMTP 将所有邮件提交到附近的(或本地主机上的)邮件服务器。这(令人惊讶地)通常比调用 mail()
更快,因为邮件调用 sendmail 实用程序,它只打开到本地主机的 SMTP 连接,at least in the case of postfix.
不要直接发送到收件人地址,因为您的生成脚本不是 MTA,因此缺少排队、延迟、错误处理、后续退回处理等;为此使用合适的邮件服务器(例如 postfix)。
不要每次循环都创建一个新的 PHPMailer 实例 - 这是一种资源浪费。仅仅因为它没有 SMTP 开销那么大并不意味着它值得丢弃,尽管阿姆达尔定律当然适用。设置循环外所有收件人共有的所有内容(例如主题)。 PHP 中的真实线程并不简单,但您可以轻松地分叉多个进程(比您拥有的 CPU 核心更多;请参阅 pcntl 扩展),因为它们大多是网络绑定的。您可能会发现在诸如 beanstalkd 之类的东西中预先排队您的消息以允许您的工作进程尽可能快地继续发送是很有用的。
在您的第一个示例中,您没有清除每封邮件之间的收件人数组,因此第一封邮件将发送给第一个收件人,第二封邮件将发送给第二个 和第一个 收件人等等。您需要在循环结束时调用 $mail->clearAllAddresses()
。
您应该使用 SMTPKeepAlive,尤其是当您使用附近的中继时,因为它会大大减少 SMTP 开销。
有关更完整的示例,请参阅 the example included with PHPMailer。
执行所有这些操作,您可以轻松达到每秒数百条消息。
我写了一个邮件脚本 phpmailer/swiftmail 支持。实际上,小型活动效果很好,所有邮件都能到达收件人,没有垃圾邮件或服务器资源问题。
我对每个连接的发送性能有疑问。哪种方式更适合发送操作? (订阅者特定的不同邮件正文)
第一个场景;
- 打开时事通讯数据
- 在任务列表中捕获 100 个订阅者
- 为每个订阅者替换新闻稿 Data/Header 并保存到新数组
- 调用 PhpMailer - 通用 SMTP 连接设置
$mail->SMTPKeepAlive = true; foreach($newArray as $k=>$v){ $mail->AddAddress($k, $v['name']); $mail->Subject = $v['subject']; $mail->Body = $v['content']; $mail->Send(); } $mail->smtpClose();
第二种情况(我的脚本中的当前方法,我已将 phpmailer class 调用到记录循环中);
- 打开时事通讯数据
- 打开任务列表 100 条记录
while($rs = $sql->fetch_assoc()){ Replace Newsletter Data/Header Call PhpMailer - Common SMTP Connection settings $mail->SMTPKeepAlive = true; $mail->AddAddress($rs['mail'], $rs['name']); $mail->Subject = $campRs['subject']; $mail->Body = $campRs['content']; $mail->Send(); } $mail->smtpClose();
我对此感到困惑,如果我使用大量邮件列表,可能会出现服务器或脚本问题吗?
此致!
发送电子邮件所花的绝大部分时间是您的网络服务器和与之通信的 SMTP 服务器之间的 SMTP 通信。
这两种情况的速度可能相当快。
如果您需要提高性能,请考虑让多个线程同时发送到不同的电子邮件地址。
从 PHPMailer 发送的最快方法是通过 SMTP 将所有邮件提交到附近的(或本地主机上的)邮件服务器。这(令人惊讶地)通常比调用 mail()
更快,因为邮件调用 sendmail 实用程序,它只打开到本地主机的 SMTP 连接,at least in the case of postfix.
不要直接发送到收件人地址,因为您的生成脚本不是 MTA,因此缺少排队、延迟、错误处理、后续退回处理等;为此使用合适的邮件服务器(例如 postfix)。
不要每次循环都创建一个新的 PHPMailer 实例 - 这是一种资源浪费。仅仅因为它没有 SMTP 开销那么大并不意味着它值得丢弃,尽管阿姆达尔定律当然适用。设置循环外所有收件人共有的所有内容(例如主题)。 PHP 中的真实线程并不简单,但您可以轻松地分叉多个进程(比您拥有的 CPU 核心更多;请参阅 pcntl 扩展),因为它们大多是网络绑定的。您可能会发现在诸如 beanstalkd 之类的东西中预先排队您的消息以允许您的工作进程尽可能快地继续发送是很有用的。
在您的第一个示例中,您没有清除每封邮件之间的收件人数组,因此第一封邮件将发送给第一个收件人,第二封邮件将发送给第二个 和第一个 收件人等等。您需要在循环结束时调用 $mail->clearAllAddresses()
。
您应该使用 SMTPKeepAlive,尤其是当您使用附近的中继时,因为它会大大减少 SMTP 开销。
有关更完整的示例,请参阅 the example included with PHPMailer。
执行所有这些操作,您可以轻松达到每秒数百条消息。