SwiftMailer 库执行缓慢

发布于 2024-11-09 10:36:51 字数 2843 浏览 0 评论 0原文

我正在尝试将 swiftmailer 实施到这个邮件系统中。我的客户有大约 30 万封活跃电子邮件需要半定期发送。该系统最初是为 sendmail 和 php 的 mail() 函数配置的。我已经安装了最新版本的 postfix。

可能是我的期望太高了,但我的印象是这个东西可以快速地将大量电子邮件放入队列中,这正是我所需要的。所有速率处理和限制都是在后缀端完成的,因此能够以我的后缀设置可以处理的速度对它们进行排队会很棒。

虽然我可以实现将联系人直接插入队列的方法,但我宁愿根据各种选项(例如 smtp 服务器的全局发送速率)限制进入队列的电子邮件的输入。

下面的代码只是要测试的基本内容。它循环访问 30 个独立的邮件 smtp 帐户,每个帐户都有自己的费率属性。我试图从每个 cron 的数据库中提取最大数量的电子邮件,然后使用 batchsend() 发送所有电子邮件,然后循环到下一个 smtp 帐户,发送最大数量等......

从技术上讲,它确实有效,但速度确实很慢。以每个 smtp 帐户 60/分钟的速率,每个大约需要 15-20 秒,这显然不起作用,而且根本不符合我的预期。

为什么发送速度这么慢,有什么非常明显的事情吗? smtp 服务器看起来很好,没有过载或类似的情况。没有后缀错误,没有什么明显的。

一旦电子邮件进入队列,我就让 postfix 工作,这太神奇了。以合理的速度将其放入队列变得很困难。我知道 swiftmailer 是解决我所有问题的神奇解决方案,但我确信它的发送速度应该比现在更快。有什么想法或建议吗?

$query = "SELECT * FROM `smtp`";
    $result = mysql_query($query) or die(mysql_error());
    $num_rows1 = mysql_num_rows($result);
    while($row = mysql_fetch_array($result)){
        $smtp = $row['ip'];
        $login = $row['user'];
        $pass = $row['pass'];
        $smtp_domain = $row['domain'];   

    $querya = "SELECT * FROM `mailer_lists` ml JOIN `mailer_controller` mc ON ml.project_name = mc.project_name LIMIT ".$global_limit."";
    $resulta = mysql_query($querya) or die(mysql_error());
    $num_rows2 = mysql_num_rows($resulta);

    // quickly check if any mail returned query
    if ($num_rows2 < 1){
        mysql_close($connection);
        echo "Nothing to mail... \n";
        die();
        }

    while($rowa = mysql_fetch_array($resulta)){
        $email[] = $rowa['email'];
        $project_name = $rowa['project_name'];
        $from_name = $rowa['from_name'];
        $subject = $rowa['subject'];
        $body = $rowa['body'];
        $from = array($spun_from_email => $spun_from_name);
    }    

    require_once 'swift/swift_required.php';
        $transport = Swift_SmtpTransport::newInstance(''.$smtp.'', 25)
          ->setUsername($login)
          ->setPassword($pass)
          ;
        $mailer = Swift_Mailer::newInstance($transport);
        $message = Swift_Message::newInstance()
          ->setSubject($subject)
          ->setFrom($from)
         // ->addPart('add part message', 'text/html')
         // ->attach(Swift_Attachment::fromPath(''))
          ->setTo($email)
          ->setBody($body)
        ;
        $mailout = $mailer->batchSend($message);
         // ->addPart('add part message', 'text/html')
         // ->attach(Swift_Attachment::fromPath(''))
          ;  


            $queryb = "DELETE FROM `mailer_lists` WHERE `project_name` = '".$project_name."' AND `email` = '".implode('\' OR `email` = \'',$email)."'";  
            $resultb = mysql_query($queryb) or die(mysql_error());
            $c++;
            echo "sent $num_rows1 emails to smtp $c \n";
        }

I'm trying to implement swiftmailer into this mailing system. my client has about 300k active emails that need to be sent on a semi regular basis. the system was originally configured for sendmail and php's mail() function. I've since installed the latest version of postfix.

it may be my expectations were way too high but i was under the impression this thing can put a lot of emails into the queue FAST, which is exactly what i need. all the rate handling and throttling is done on the postfix side, so being able to queue them as fast as my postfix settings can handle would be great.

while i could implement methods to insert the contact directly into the queue, i'd rather limit the input of emails going into the queue based on various options such as global send rates for the smtp server.

the code below is just something basic to test. it loops through 30 separate mailing smtp accounts, each with it's own rate properties. i'm trying to pull the max amount of emails out of the db per cron, then send then all using batchsend(), then loop to the next smtp account, send max, etc..

technically it does work, however it's really slow. at a rate of 60/min per smtp account, it takes about 15-20 seconds each which obviously will not work and not at all what i had expected.

is there something really obvious about why this would send so slow? the smtp servers appear to be fine, no overload or anything like that. no postfix errors, nothing obvious.

once the emails make it to the queue, i let postfix work it's magic. it's getting it into the queue at a reasonable rate that's become difficult. i know swiftmailer is a magic solution to all my problems, but i'm sure it should be sending quicker than it is. any ideas or suggestions?

$query = "SELECT * FROM `smtp`";
    $result = mysql_query($query) or die(mysql_error());
    $num_rows1 = mysql_num_rows($result);
    while($row = mysql_fetch_array($result)){
        $smtp = $row['ip'];
        $login = $row['user'];
        $pass = $row['pass'];
        $smtp_domain = $row['domain'];   

    $querya = "SELECT * FROM `mailer_lists` ml JOIN `mailer_controller` mc ON ml.project_name = mc.project_name LIMIT ".$global_limit."";
    $resulta = mysql_query($querya) or die(mysql_error());
    $num_rows2 = mysql_num_rows($resulta);

    // quickly check if any mail returned query
    if ($num_rows2 < 1){
        mysql_close($connection);
        echo "Nothing to mail... \n";
        die();
        }

    while($rowa = mysql_fetch_array($resulta)){
        $email[] = $rowa['email'];
        $project_name = $rowa['project_name'];
        $from_name = $rowa['from_name'];
        $subject = $rowa['subject'];
        $body = $rowa['body'];
        $from = array($spun_from_email => $spun_from_name);
    }    

    require_once 'swift/swift_required.php';
        $transport = Swift_SmtpTransport::newInstance(''.$smtp.'', 25)
          ->setUsername($login)
          ->setPassword($pass)
          ;
        $mailer = Swift_Mailer::newInstance($transport);
        $message = Swift_Message::newInstance()
          ->setSubject($subject)
          ->setFrom($from)
         // ->addPart('add part message', 'text/html')
         // ->attach(Swift_Attachment::fromPath(''))
          ->setTo($email)
          ->setBody($body)
        ;
        $mailout = $mailer->batchSend($message);
         // ->addPart('add part message', 'text/html')
         // ->attach(Swift_Attachment::fromPath(''))
          ;  


            $queryb = "DELETE FROM `mailer_lists` WHERE `project_name` = '".$project_name."' AND `email` = '".implode('\' OR `email` = \'',$email)."'";  
            $resultb = mysql_query($queryb) or die(mysql_error());
            $c++;
            echo "sent $num_rows1 emails to smtp $c \n";
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

雪落纷纷 2024-11-16 10:36:51

您的问题不在于您正在使用的库。这很慢,因为您正在向电子邮件服务器发送大量数据......所以 postfix 会在回复您之前尝试处理所有数据。尝试一次发送一封电子邮件而不关闭连接,这样电子邮件服务器就可以更快地处理您发送给它的每封电子邮件,并更快地返回答案。

  • 将以下行移至脚本顶部

require_once 'swift/swift_required.php';

  • 建立与 smtp 服务器的惰性连接。 您不需要每次要发送电子邮件时都进行连接。在顶部连接一次并检查连接是否有效(否则再次连接),发送电子邮件并清除字段tofrom 等...

  • 从顶部的数据库中获取您的 smtp 设置,然后删除巨大的 while.这根本不会使代码可读

Your problem is not the library you are using. This is being slow because you are sending a big chunk of data to the email server...so postfix is trying to process all before replying you. Try sending ONE email at the time without closing the connection, so this way the email server can process faster each email you send to it and return an answer faster too.

  • move the following line to the top of the script

require_once 'swift/swift_required.php';

  • Make the connection to the smtp server lazy. You don't need to connect every time you want to send an email. Connect once at the top and check if the connection is alive (otherwise connect again), send the email and clear the fields to, from, etc...

  • grab your smtp settings from the database at the top then remove the giant while. That doesn't make the code readable at all

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文