День добрый хабр!
Не так давно в компании, где я работаю, дали задачу найти и проанализировать все почтовые сообщения, которые уходят с нашего портала, а позже создать единый интерфейс для работы с почтой. Такой небольшой корпоративный почтовый сервиc.
Для реализации данной задачи можно создать класс с разными функциями для отправки разных типов сообщений (обычные текстовые сообщения для админов, html-сообщения для клиентов и комбинированные с прикрепленными файлами) или использовать одну из библиотек (swiftmailer и phpMailer).
Для начала я решил протестировать производительность библиотек, для теста был выбран локальный почтовый адрес и метод отправки через стандартный mail() php.
Так как с нашего ресурса уходит около 500 сообщений день в штатном режиме и около 5000 в самый пиковый момент — скорость работы скриптов отправки — достаточно больной вопрос.
В нашей коменде 3 джуна, которым обязательно придется ковыряться в коде — простота понимания и использования также имеют ценность.
Для тестирования работы я создал пару небольших скриптов:
swift_test_speed.php
<?php
include_once 'vendor/autoload.php';
#Как не странно swiftmailer нужно подключать отдельно, стандартный autoload composer не работает
include_once 'vendor/swiftmailer/swiftmailer/lib/swift_required.php';
$from = 'noreply@example.com';
$to = 'dev@vector';
$subject = 'testmail';
$htmlBody = '<h1>Html letter</h1>';
$textBody = 'text body';
$file1 = '../logos/logo1.png';
$file2 = '../logos/logo2.gif';
#test swift
echo $start_time=microtime(TRUE); echo "n";
for($i=1; $i<100; $i++){
$swift_message = Swift_Message::newInstance()
->setReplyTo($from,'noreply')
->setFrom($from,'noreply')
->setSubject($subject.' - swift')
->setReturnPath($from)
->setTo($to)
->setBody($htmlBody,'text/html')
->addPart($textBody,'text/plain')
->attach(Swift_Attachment::fromPath($file1))
->attach(Swift_Attachment::fromPath($file2));
$swift_transport = new Swift_MailTransport();
$swift_mailer = new Swift_Mailer($swift_transport);
$swift_mailer->send($swift_message);
}
echo $swift_time = microtime(TRUE); echo "n";;
echo 'swift = '.($swift_time - $start_time);
и php-mailer.php
<?php
include_once 'vendor/autoload.php';
$from = 'noreply@example.com';
$to = 'dev@vector';
$subject = 'testmail';
$htmlBody = '<h1>Html letter</h1>';
$textBody = 'text body';
$file1 = '../logos/logo1.png';
$file2 = '../logos/logo2.gif';
#test phpmailer
echo $start_time=microtime(TRUE); echo "n";
for($i=1; $i<100; $i++) {
$php_mailer = new PHPMailer();
$php_mailer->setFrom($from);
$php_mailer->addAddress($to);
$php_mailer->addAttachment($file1);
$php_mailer->addAttachment($file2);
$php_mailer->isMail();
$php_mailer->From = 'noreply@prodengi.kz';
$php_mailer->FromName = 'noreply';
$php_mailer->isHTML(true);
$php_mailer->Body = $htmlBody;
$php_mailer->Subject = $subject;
$php_mailer->AltBody = $textBody;
$php_mailer->send();
}
echo $php_mailer_time = microtime(TRUE); echo "n";
echo ' : phpmailer = '.($php_mailer_time-$start_time);
Для теста отправки была выбрана задача: отослать 100 сообщений с 2-я файлами.
Результаты следующие:
swift = 17.824028015137
phpmailer = 18.63211107254
При отправке 100 сообщений выигрыш при использовании swift — 1 секунда.
При отправке 5000 в теории разрыв должен быть около 50 секунд.
Но при тесте 5000 разрыв оказался куда большим — 3 минуты.
После проведения теста я позвал тимлида и джунов спросить, какой код для них более понятен.
Так как в phpMailer код оказался немного проще, то для задачи была выбранна либа phpMailer, но при повышении нагрузок все-таки лучше использовать swiftMailer.
Итог: swift оказался чуть быстрее, чем phpMailer.