Amazon Ses PHP SDK 2 - Как добиться высокой скорости отправки


Отправка электронных писем с использованием метода sendEmail класса SesClient из PHP SDK в настоящее время занимает около половины секунды на одно электронное письмо. Я просматриваю массив получателей и устанавливаю свойство message ToAddresses равным массиву, содержащему только адрес электронной почты получателя, перед вызовом sendEmail(). Я хотел бы ускорить процесс отправки, но мне кажется, что класс PHP, предоставляемый SDK, выполняет один запрос на сообщение (в моем случае, получатель). (Возможно, одно соединение на сообщение?)

Я немного почитал и подумал об использовании свойства BccAddresses для отправки электронных писем партиями, но мы хотели бы, чтобы заголовок To: был явно задан, а не просто "нераскрытые получатели", поэтому я хотел бы знать, есть ли у кого-нибудь лучший подход.

Author: idrarig, 2013-05-30

2 answers

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

В качестве альтернативы вы можете просто доставлять электронные письма в нескольких потоках (возможно, нетривиальных в PHP). Вот пример в ruby с aws-sdk-ruby.

  require aws-sdk
  ses = AWS::SimpleEmailService.new(:access_key_id => 'ACCESS_KEY', :secret_access_key => 'SECRET_KEY')
  pool = Array.new(ses.quotas[:max_send_rate]) do |i|
    Thread.new do
      ses.send_email(
        :subject => 'subject',
        :body_html => 'body_html',
        :body_text => 'body_text',
        :to => '[email protected]',
        :source => '[email protected]',
      )
    end
  end

  sleep(1)
  pool.each(&:join)
 0
Author: desheikh, 2013-06-12 05:17:06

Для тех, кто сталкивается с AWS и SES, пытаясь решить эту проблему параллельных запросов, выполняемых при постоянном подключении, AWS SDK 2 и выше поддерживает это в php с использованием командных объектов.

Клиент SesClient и другие клиенты могут выполнять команды параллельно. Это обычный метод для запуска одного соединения и отправки электронной почты через SES:

$result = $client->sendEmail(array(
    //email data
));

Клиентские объекты очень мощные и наследуют множество методов для выполнения запросов и управления ими такие как getCommand() и execute(). Потребовалось много часов копания, прежде чем я нашел простое решение! Вам просто нужно знать, что нужно искать. Вот пример:

$commands = array();
$commands[] = $sesClient->getCommand('SendEmail', array(
    //email data
));
$commands[] = $sesClient->getCommand('SendEmail', array(
    //email data
));

// Execute an array of command objects to do them in parallel
$sesClient->execute($commands);

// Loop over the commands, which have now all been executed
foreach ($commands as $command) {
    $result = $command->getResult();
    // Do something with result
}

Обработка ошибок может быть достигнута путем выполнения следующего кода:

use Guzzle\Service\Exception\CommandTransferException;

try {
    $succeeded = $client->execute($commands);
} catch (CommandTransferException $e) {
    $succeeded = $e->getSuccessfulCommands();
    echo "Failed Commands:\n";
    foreach ($e->getFailedCommands() as $failedCommand) {
        echo $e->getExceptionForFailedCommand($failedCommand)->getMessage() . "\n";
    }
}

Amazon документирует эти примеры в своем руководстве для разработчиков в разделе функция команд.

 5
Author: Macadameane, 2014-11-18 18:39:12