PHP, sendmail и транспорты - как ускорить отправку почты - PullRequest
6 голосов
/ 12 июля 2011

Я только что написал набор классов массовых рассылок для обработки огромного количества писем и анализа их содержимого в соответствии с переданными параметрами.Если я проверяю электронную почту на 1000 случайных получателей и 1000 случайных отправителей из моей базы данных, вплоть до момента, когда сценарий достигает части send () (я это прокомментировал на данный момент), я получаю производительность около 2 секунд и 20 МБ пиковой памяти, что здорово.

Однако, если я раскомментирую отправляющую часть, отправка займет 30 секунд.Это недопустимо, и я хотел бы как-то ускорить его.Из тестирования очевидно, что задержка вызвана не чем иным, как вызовом $ mail-> send (), как если бы он ожидал, чтобы он возвратил что-то перед продолжением цикла и отправкой следующего письма.

ЧтоМне интересно: как мне ускорить вызов send ()?Что я могу сделать, чтобы сделать это быстрее?Я попытался использовать два метода отправки:

  1. Транспорт Zend SMTP, подключение к серверу напрямую и просто отправка.Это занимает 30 секунд на 1000 писем.
  2. Sendmail via Zend_Mail.Просто вызывая функцию отправки Zend_Mail после подготовки каждого письма.Это занимает 60 секунд.

Обратите внимание, что организация очередей определенно является опцией, и я встроил ее в свои классы.Все, что нужно, это активировать cron, и это работает как заклинание.Но я задаюсь вопросом о фактической отправке и как ускорить это.Итак, фактический вызов send ().

Ответы [ 3 ]

2 голосов
/ 12 июля 2011

Я бы сохранял письма в директории и отправлял их, используя скрипт оболочки (cron / daemon /...):

Zend_Mail::setDefaultTransport(
    new Zend_Mail_Transport_File(
        array(
            'path' => __DIR__,
            'callback' => function() {
                do {
                    $file = 'email-' . date('Y-m-d_H-i-s') . '_' . mt_rand() . '.eml';
                } while (file_exists($file));
                return $file;
            },
        )
    )
);
2 голосов
/ 12 июля 2011

Вам нужно будет ускорить MTA на сервере. Я рекомендую Postfix, и вы действительно читаете каждую настройку, чтобы знать, как ее настроить. Я слышал, что для коммерческого решения PowerMTA - хороший выбор, но я никогда не пробовал сам.

Вы можете выжать только одну производительность из одной машины, но обычный выделенный сервер должен быть в состоянии доставить довольно внушительный объем почты, как только вы настроите его правильно. Самым большим узким местом производительности обычно являются дисководы, на которых хранится очередь почты, поэтому рассмотрите возможность использования дисков SAS (10 или даже 15 000 об / мин) или SSD.

0 голосов
/ 12 июля 2011

Вы можете попробовать покопаться в PHP pcntl-fork функции.Таким образом, вы можете оставить отправку в другом процессе при разборе следующего письма.

PLAN B

Вы можете сериализовать и сохранить объект электронной почты в очереди базы данных и позволить другомускрипт для отправки их в фоновом режиме.Этот сценарий может выполняться в бесконечном цикле (while true) с некоторыми значениями sleep на каждой итерации.Вы даже можете запустить несколько экземпляров этого сценария, но убедитесь, что два сценария не начнут отправлять одно и то же сообщение одновременно.

Чтобы быть уверенным, что сценарий все еще выполняется, вы можете использовать monit на машинах Unix.Он может запустить скрипт, если по какой-либо причине старый экземпляр вышел из строя.

...