Подтвердить что ты не робот

Какой лучший подход к отправке электронной почты сотням получателей из приложения Zend Framework?

Я пытаюсь внедрить систему списков рассылки для своего приложения. В настоящее время я использую Zend_Mail_Transport_Smtp('localhost') как мой транспорт, просматриваю список подписчиков и отправляю новый Zend_Mail каждому. Тем не менее, я замечаю, что время, которое требуется для завершения script, увеличивается по мере увеличения количества подписчиков.

Я уверен, что для этого требуется более профессиональный подход, связанный с очередью электронных писем. Я предполагаю, что идеальный подход состоял бы в том, чтобы пользователь заполнил форму, щелкнул отправить и сразу получил ответ, в котором говорилось, что электронные письма отправляются, а не ждать, пока сотни писем будут отправлены.

Я понимаю, что Zend_Mail не выполняет сортировку по очереди. Может ли кто-нибудь, кто имеет опыт работы с этим, дать мне обзор того, как это можно сделать? Я ничего не знаю о cron/crontab/cronjobs, поэтому, если это связано с этим, пожалуйста, объясните процесс.

4b9b3361

Ответ 1

Чтобы надежно отправлять большое количество писем с помощью PHP, вам нужно использовать механизм очередей. Как было предложено другими, процесс использования очереди выглядит примерно так:

  • Завершите работу над вашим набором пользователей, создав электронное письмо для каждого из них и, возможно, настроив содержимое
  • Передайте каждый почтовый объект в очередь, которая будет откладывать отправку электронной почты до более позднего времени.
  • В некотором роде cron script отправьте содержимое очереди несколько сотен за раз. Примечание. Вы хотите настроить количество отправляемых сообщений электронной почты, просмотрев журналы для ошибок, возвращаемых из фактического процесса отправки. Если вы попытаетесь отправить слишком много, я заметил, что он достигает точки, в которой почтовый транспорт больше не будет принимать соединения (я использую qmail)

Есть несколько библиотек, которые вы можете использовать для этого, PEAR Mail Queue (с Mail_Mime) и SwiftMailer позволяют создавать и очереди сообщений электронной почты. Пока Zend Mail предоставляет только создание писем, а не очередей (подробнее об этом позже).

У меня есть опыт в основном с PEAR Mail Queue и есть несколько ошибок. Если вы пытаетесь поставить в очередь большое количество писем (например, зацикливая более 20 000 пользователей и пытаясь завести их в очередь в разумные сроки), использование реализаций кодирования с использованием кавычек с поддержкой Mail Mime выполняется очень медленно. Вы можете ускорить это, переключившись на кодировку base64.

Что касается Zend Mail, вы можете написать объект Zend Mail Transport, который помещает ваши объекты Zend Mail в очередь PEAR Mail Queue. Я сделал это с некоторым успехом, но для его исправления требуется немного времени. Для этого увеличьте Zend Mail Transport Abstract, внедрите метод _sendMail (в котором вы поместите свой объект Zend Mail в очередь почты) и передайте экземпляр вашего транспортного объекта методу send() вашего объекта Zend Mail или по Zend Mail:: setDefaultTransport().

Суть в том, что есть много способов сделать это, но от вашего имени потребуются некоторые исследования и обучение. Однако это очень разрешимая проблема.

Ответ 2

ПРИМЕЧАНИЕ. Когда я впервые прочитал ваш вопрос, я подумал, что он сказал сотни тысяч писем сразу. Когда я дважды проверял, я заметил, что это на самом деле говорило от сотен до тысяч. Я слишком ленив, чтобы изменить свой пост сейчас, так что вот некоторые предостережения: по моему опыту, вы, вероятно, можете нормально работать без коммерческого инструмента примерно до 40K. Примерно в 10K вы захотите следить за "минимальным" списком, чтобы предотвратить большую боль, когда вы начнете достигать больших размеров списка. Я рекомендую все это сразу сделать.

Я уже говорил об этом, есть две стороны для отправки электронной почты:

  • Техническая сторона - в основном все RFC вокруг smtp протокол, форматы электронной почты, DNS записей и т.д. Это мягко сложный, но разрешимый.
  • Волшебная сторона - доставка по электронной почте управление вуду. Ты получишь разочарованы, все пойдет на нет очевидная причина, и вы рассмотреть вопрос о выезде на другую работу который не связан с электронной почтой.

Я не рекомендую писать собственный отправитель. Я уверен, что PHP может отлично справиться, но вы, вероятно, должны провести время в другом месте. Два продукта, которые я использовал в прошлом и рекомендую, это Strongmail и PowerMTA. Будьте осторожны - у них высокая цена, но я могу почти гарантировать, что вы потратите больше средств на собственное решение в долгосрочной перспективе.

Одной областью, в которой вы будете прибиты при написании своего собственного PHP, является дросселирование/детонация. Почтовые серверы начнут добавлять во сне (30) после того, как вы отправите несколько сообщений, чтобы замедлить работу и остановить вас от спама.

Как правило, эти коммерческие массовые отправители запускают протокол SMTP для организации очередей. Вы продолжаете использовать Zend_Mail, но жесткий код для подключения к вашему серверу. Он будет отправлять почту в очередь так быстро, как вы можете отправить ее, а затем использовать ее собственный движок для отправки почты в свои адресаты.

В списке 100K вам нужно будет использовать лучшие практики электронной почты. Как минимум, вам понадобится:

  • Записи SPF, возможно, DKIM, а также
  • Несколько IP-адресов для сегментации трафика - имеют 3 IP-адреса, по одному для вашего качественного адреса, один для IP-адресов среднего риска и один для IP-адресов высокого риска. Этот дизайн помогает минимизировать риск получения почты для ваших лучших клиентов.
  • Правильный обратный DNS для отправки IP-адресов
  • Используйте петли обратной связи от AOL, hotmail, yahoo и других для обработки жалоб на спам.
  • Отменить подписку и управление откатом - убедитесь, что вы обрезаете эти адреса.
  • Отслеживание открытий и кликов также важно - если вы являетесь клиентом в списке A, вы не открываете свои электронные письма, вы должны деградировать их в списке B и так далее. Это важно, потому что интернет-провайдер превратит неактивные аккаунты в honeypot. Hotmail известен этим.

Наконец, если вы действительно серьезно относитесь к отправке электронной почты, вам понадобятся другие инструменты, такие как Return Path.

Ответ 3

Из документации PHP.net.

Примечание. Следует отметить, что функция mail() не подходит для больших объемов электронной почты в цикле. Эта функция открывает и закрывает SMTP-сокет для каждого письма, что не очень эффективно.
Для отправки большого количества электронной почты см. " PEAR:: Mail и " PEAR:: Mail_Queue.

Класс Zend Mail, вероятно, довольно хорош (большая часть материала Zend хороша) Но если вы хотите другие варианты. Вот они.

Ответ 4

Используйте Zend_Queue, чтобы поместить электронные письма в очередь для асинхронной обработки фона. Вам понадобится задание cron для обработки очереди в фоновом режиме.

protected function _enqueueEmail(WikiEmailArticle $email)
{
    static $intialized = false; 

    if (!$initialized) {

        $this->_initializeMailQueue("wikiappwork_queue");
        $initialized = true;
    }

    $this->_mailQueue->send(serialize($email));  
}
protected function _initializeMailQueue()
{
    /* See: 1.) http://framework.zend.com/manual/en/zend.queue.adapters.html and
     *      2.) Zend/Queue/Adapter/Db/mysql.sql. 
     */

 $ini = Zend_Controller_Front::getInstance()->getParam('bootstrap')
                                            ->getOptions(); 

     $queueAdapterOptions =    array( 'driverOptions' => array(
    'host' => $ini['resources']['multidb']['zqueue']['host'],
    'username' => $ini['resources']['multidb']['zqueue']['username'],
    'password' => $ini['resources']['multidb']['zqueue']['password'],
    'dbname' => $ini['resources']['multidb']['zqueue']['dbname'],
    'type' => $ini['resources']['multidb']['zqueue']['adapter'] ),
    'name' => $ini['resources']['multidb']['zqueue']['queueName'] );

    $this->_mailQueue = new Zend_Queue('Db', $queueAdapterOptions);

 }

Затем для задания cron a script как

<?php
use \Wiki\Email\WikiEmailArticle;

// Change this define to correspond to the location of the wikiapp.work/libary
define('APPLICATION_PATH', '/home/kurt/public_html/wikiapp.work/application');

set_include_path(implode(PATH_SEPARATOR, array(
     APPLICATION_PATH . '/../library',
     get_include_path(),
 )));

// autoloader (uses closure) for loading both WikiXXX classes and Zend_ classes.
spl_autoload_register(function ($className) { 

  // Zend classes need underscore converted to PATH_SEPARATOR
  if (strpos($className, 'Zend_' ) === 0) {

        $className = str_replace('_', '/', $className );   
  }

  $file = str_replace('\\', '/', $className . '.php');

  // search include path for the file.
  $include_dirs = explode(PATH_SEPARATOR, get_include_path());

  foreach($include_dirs as $dir) {

    $full_file = $dir . '/'. $file;

    if (file_exists($full_file)) { 

        require_once $full_file; 
        return true; 
    }
  }

  return false; 
 }); 

// Load and parese ini file, grabing sections we need.
$ini = new Zend_Config_Ini(APPLICATION_PATH . 
                          '/configs/application.ini', 'production');

$queue_config = $ini->resources->multidb->zqueue;

$smtp_config = $ini->email->smtp;

$queueAdapterOptions =  array( 'driverOptions' => array(
                                        'host'      => $queue_config->host,
                    'username'  => $queue_config->username,
                    'password'  => $queue_config->password,
                    'dbname'    => $queue_config->dbname,
                    'type'      => $queue_config->adapter),
                'name' => $queue_config->queuename);

$queue = new Zend_Queue('Db', $queueAdapterOptions);


$smtp = new Zend_Mail_Transport_Smtp($smtp_config->server, array(
                'auth'      => $smtp_config->auth,
        'username'  => $smtp_config->username,
        'password'  => $smtp_config->password,
        'port'      => $smtp_config->port,
        'ssl'       => $smtp_config->ssl
        ));

Zend_Mail::setDefaultTransport($smtp);

$messages = $queue->receive(10); 

foreach($messages as $message) {

        // new WikiEmailArticle.     
    $email = unserialize($message->body);

        try {

            $email->send();

        }  catch(Zend_Mail_Exception $e) {

               // Log the error?
               $msg = $e->getMessage();
               $str = $e->__toString();
               $trace =  preg_replace('/(\d\d?\.)/', '\1\r', $str);
        } // end try

$queue->deleteMessage($message);

} // end foreach

Ответ 5

Вы должны хорошо использовать PHP в тысячах получателей, хотя избегайте почты(), как отмечали другие. Я видел несколько систем, предназначенных для большого количества почты (100 000+ получателей), которые перешли в обход стандартных функций рассылки и пытались работать более непосредственно с MTA. Даже тогда мне не было ясно, что это было необходимо.

Создание электронной почты - это больше о том, как правильно форматировать (HTML и обычный текст, когда это возможно), люди могут легко отказаться от подписки, исправления обрабатываются правильно, на почтовом сервере есть все необходимые DNS-записи, а сервер конфигурация не нарушает правила какой-либо крупной системы черных списков. Язык, на котором вы пишете приложение, не является основным фактором в нескольких сотнях или даже нескольких тысячах сообщений.

Ответ 6

Я реализовал массовую рассылку в php, где каждое электронное письмо было настроено для отдельного человека. Это было не сложно и не занимало слишком много времени. Я использовал swiftmailer и cron. Возможно, Zend Mail тоже в порядке. Я начал с очереди сообщений PEAR, но очередность сообщений электронной почты была слишком медленной.

Процесс очередей электронной почты шел следующим образом:

  • Создайте шаблон электронной почты и добавьте заполнители (или используйте механизм шаблонов) для областей, где будет заменен уникальный контент.
  • В цикле замените заполнители в любом уникальном контенте, вставьте в него содержимое электронной почты, тему, адреса, пакетный идентификатор и, при необходимости, значение приоритета в таблицу базы данных.

Я использовал задание cron для отправки партий писем. Временной интервал cron и количество отправленных сообщений в рассылке были важны, так как я был на общем узле с ограничениями. script, который был вызван заданием cron, был доступен только cron. script прочитайте x количество электронных писем из таблицы, упорядоченной с помощью идентификатора пакета и, при желании, приоритетом. Если письмо было успешно отправлено, оно было удалено из очереди базы данных. Если электронное письмо не может быть отправлено, оно оставалось в очереди, и счетчик был увеличен для этой записи. Если счетчик превысил установленное число, тогда сообщение было удалено из очереди.

Ответ 7

Класс Zend Mail выглядит хорошо и прост в использовании, он также позволяет отправлять простой текст и HTML-версию электронного письма, что в маркетинге электронной почты очень важно.

Если вы знакомы с работой фрейма, я буду придерживаться его.

Важные вещи, которые следует учитывать при отправке писем на большие тома людей:

  • Может ли ваш веб-сервер справляться с запросами на изображение при открытии электронной почты + загрузка на сервере людей, посещающих ваш сайт.

Если ответ отрицательный или ваш неуверенный, использование теста apache должно помочь вам в разработке, если это возможно. Если вы все еще не уверены, всегда лучше всего отправлять электронные письма (которые могут быть синхронизированы с помощью crontab) для распространения нагрузки.

Надеюсь, это поможет.

Ответ 8

Я разработал систему управления рассылкой новостей Swiftmailer, и это очень просто реализовать. Он поддерживает SMTP, шифрование, вложения, пакетную передачу,...