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

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

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

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

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

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

  • Прокрутите список пользователей, создайте электронное письмо для каждого и, возможно, настроив контент
  • Передайте каждый почтовый объект в очередь, которая будет задерживать отправку электронной почты до следующего
  • В каком-то cron-скрипте отправьте содержимое очереди несколько сотен за раз. Примечание. Вы хотите настроить количество отправляемых сообщений электронной почты, просмотрев журналы для ошибок, возвращаемых из фактического процесса отправки. Если вы попытаетесь отправить слишком много, я заметил, что он достигает точки, в которой почтовый транспорт больше не будет принимать соединения (я использую 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. Я сделал это с некоторым успехом, но для его исправления требуется немного времени. Для этого увеличьте Zend Mail Transport Abstract, внедрите метод _sendMail (в котором вы поместите свой объект Zend Mail в очередь почты) и передайте экземпляр вашего транспортного объекта методу send () вашего объекта Zend Mail или по Zend Mail :: setDefaultTransport ().

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

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

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

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

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

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

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

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

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

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

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

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

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

Используйте 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 скрипт вроде

 <?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 

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

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

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

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

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

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

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

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

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

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

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

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

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