【问题标题】:Sending newsletter using PHP SwiftMailer and SMTP使用 PHP SwiftMailer 和 SMTP 发送时事通讯
【发布时间】:2013-11-10 01:59:59
【问题描述】:

我每天都会向大约 20,000 个收件人发送时事通讯。移动到其他服务器后,使用相同的 PHP 脚本,我需要大约六倍的时间——我尝试了许多不同的设置,但都没有成功 (please see this post)。电子邮件服务器似乎配置正确(关于垃圾邮件、中继和病毒),服务器运行 Plesk 11.5.30。

做了很多实验,更改了 PHP 脚本和 Postfix 设置,我能够通过以下方式获得最佳性能:

  1. 使用 SwiftMailer 从 PHP 发送电子邮件。
  2. 使用 SMTP(本地帐户)作为传输。
  3. 将收件人列表分为四部分,并为每一部分启动单独的 PHP-CLI 进程。

当我只启动一个进程时,PHP 每秒发送大约 5 封电子邮件(这与我使用 mail() 函数发送电子邮件时大致相同)。 Postfix 可以“即时”发送它们,因此几乎没有队列。

当我启动四个进程时,PHP 每秒发送大约 10 封电子邮件,但是 postfix 不再能够“即时”发送它们(它每秒只能发送大约 5 封电子邮件),因此队列变得越来越大。 PHP 进程结束后,我的队列中有大约 4500 封电子邮件。有趣的部分来了:当没有更多活动的 PHP 进程发送电子邮件时,Postfix“加速”到每秒发送大约 20 封电子邮件。当 PHP 发送新电子邮件时,Postfix 是否能够以这种速率发送电子邮件?不会有队列,它会解决我的问题。

如果我能做些什么来提高我的脚本和发送时事通讯的服务器的性能,我将不胜感激。

Postfix 配置来了:

root@hostname:~# postconf -n 
alias_database = hash:/etc/aliases 
alias_maps = hash:/etc/aliases, hash:/var/spool/postfix/plesk/aliases 
append_dot_mydomain = no 
biff = no 
config_directory = /etc/postfix 
disable_vrfy_command = yes 
inet_interfaces = all 
inet_protocols = ipv4 
mailbox_size_limit = 0 
mailman_destination_recipient_limit = 1 
message_size_limit = 51200000 
mydestination = (none), localhost, localhost.localdomain, localhost 
mydomain = domain.com 
myhostname = myhostname.com 
mynetworks = 127.0.0.0/8 [::1]/128 my.ip.add.ress 
plesk_virtual_destination_recipient_limit = 1 
readme_directory = no 
recipient_delimiter = + 
relayhost = 
sender_dependent_default_transport_maps = hash:/var/spool/postfix/plesk/sdd_transport_maps 
smtp_connect_timeout = 10s 
smtp_helo_timeout = 100s 
smtp_send_xforward_command = yes 
smtp_tls_security_level = may 
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache 
smtp_use_tls = no 
smtpd_authorized_xforward_hosts = 127.0.0.0/8 [::1]/128 
smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU) 
smtpd_client_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_rbl_client zen.spamhaus.org 
smtpd_proxy_timeout = 3600s 
smtpd_recipient_restrictions = permit_mynetworks, check_client_access pcre:/var/spool/postfix/plesk/no_relay.re, permit_sasl_authenticated, reject_unauth_destination 
smtpd_sasl_auth_enable = yes 
smtpd_sender_restrictions = check_sender_access hash:/var/spool/postfix/plesk/blacklists, permit_sasl_authenticated, check_client_access pcre:/var/spool/postfix/plesk/non_auth.re 
smtpd_timeout = 3600s 
smtpd_tls_cert_file = /etc/postfix/postfix_default.pem 
smtpd_tls_key_file = $smtpd_tls_cert_file 
smtpd_tls_security_level = may 
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache 
smtpd_use_tls = yes 
transport_maps = , hash:/var/spool/postfix/plesk/transport 
virtual_alias_maps = $virtual_maps, hash:/var/spool/postfix/plesk/virtual 
virtual_gid_maps = static:31 
virtual_mailbox_base = /var/qmail/mailnames 
virtual_mailbox_domains = $virtual_mailbox_maps, hash:/var/spool/postfix/plesk/virtual_domains 
virtual_mailbox_limit = 0 
virtual_mailbox_maps = , hash:/var/spool/postfix/plesk/vmailbox 
virtual_transport = plesk_virtual 
virtual_uid_maps = static:110

【问题讨论】:

  • 如果您的 PHP 进程完成后 Postfix 变得更快,那么您可能遇到了 CPU 问题?当 PHP 进程运行时,top 会说什么?你是在共享服务器上还是在 VPS 上?什么规格?
  • 我们使用专用服务器,实际上并没有太多事情要做。 CPU 和内存不是问题——我们有足够的资源(我今天在发送时事通讯时再次检查了这一点)。运行 iostat -m -x -d 5 我看到磁盘使用率非常高(%util 高达 100% - PHP 和 Postfix 完成后大约为 10% - 这可能与我们的性能问题有关吗?)什么我不明白的是,为什么新服务器上的 PHP 能够在一个进程中最多发送 5-7 封邮件/秒(如果你只运行一个进程),而我们的旧服务器每秒能够发送 20 封甚至更多。
  • 我不是服务器问题方面的专家,但当然,100% 的事情都值得进一步调查。它是否说明 PHP 和 Postfix 中的哪一个负责该级别的使用?
  • PHP 似乎是造成高使用率的原因。我真正不喜欢的是我必须启动许多进程。在旧服务器上,我启动了一个进程,PHP 能够“传输”大约 20 封邮件/秒到 Postfix。所以问题是我必须做些什么来加快 PHP 的发送邮件速度。
  • 邮件日志中没有关于“不合格的主机名”或“失败的名称解析”的信息?听起来好像一切都发生了,很难用“发生了什么变化”来诊断。

标签: php email postfix-mta swiftmailer newsletter


【解决方案1】:

嘿,我找不到您的设置的确切问题,但我已经阅读了可能有助于找到确切时间延迟的 cmets。请参考http://ubuntuforums.org/showthread.php?t=2007309,也可以通过http://liangsun.org/posts/configure-mail-service-with-php-mail-function-and-postfix/重新检查您的代码

有关 swiftmailer 的设置,请参阅 https://bbs.archlinux.org/viewtopic.php?id=82062

【讨论】:

    【解决方案2】:

    由于您写到您的 PHP 进程每秒发送大约 5 或 20 封邮件,我假设您已经在详细测量您的 PHP 代码,所以如果这种延迟出现在 PHP 代码中,您应该已经发现了。

    阅读 cmets 我还假设您的系统很大,因此您有足够的内存和磁盘。

    根据我的经验,可能导致此类延迟的一个非常常见的问题是 DNS 解析,我的意思是 DNS 的错误配置,这会导致延迟。 但这个假设还有待证明。

    另一方面,我什至记得 postfix 有一个节流配置,以避免服务器滥用。 http://www.postfix.org/TUNING_README.html

    最后,如果您在 postfix 配置中找不到任何东西,我可以建议您尝试在 postfix 执行过程中使用实用程序 strace 对其进行调试。

    这是一个非常有用的实用程序,当我必须调试非常见问题时,我经常使用它。 简而言之: strace 列出进程完成的所有系统调用。 strace中有很多可用的选项,但我通常只使用:

    strace -fp <pid of main process>
    

    在调试期间,您将看到所有由 postfix 主进程及其所有子进程执行的系统调用。如果添加 -c 选项,那么您将看到每个系统调用所花费的时间。

    【讨论】:

      【解决方案3】:

      感谢您的所有回答和努力。幸运的是,我能够找到问题的主要原因 - 将队列保存在硬盘上。我们将其更改为 RAM,现在每秒可以发送大约 30 封电子邮件。

      【讨论】:

        猜你喜欢
        • 2017-04-16
        • 2014-08-17
        • 1970-01-01
        • 2012-03-08
        • 1970-01-01
        • 1970-01-01
        • 2012-01-08
        • 2012-02-25
        • 2012-01-07
        相关资源
        最近更新 更多