Amazon Ses PHP SDK 2 -如何实现高发送率


Amazon Ses PHP SDK 2 - How to achieve high send rate

使用PHP SDK的SesClient类的sendEmail方法发送电子邮件目前每封电子邮件大约需要半秒。在调用sendEmail()之前,我循环遍历收件人数组,并将消息ToAddresses属性设置为等于仅包含收件人电子邮件地址的数组。我想加快发送过程,但在我看来,SDK提供的PHP类对每个消息(在我的情况下是接收者)执行一个请求。(可能每条消息一个连接?)

我做了我的一点阅读,我考虑使用BccAddresses属性来批量发送电子邮件,但我们希望To:头明确设置,而不是说只是"未公开的收件人",所以我想知道是否有人有更好的方法。

对于那些通过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在其开发者指南的命令特性下记录了这些示例。

我过去使用PHP和AWS所做的是在数据库中设置一个电子邮件队列,并让多个进程在此基础上工作以发送电子邮件。

或者您可以在多个线程中传递电子邮件(在PHP中可能不是微不足道的)。下面是一个使用aws-sdk-ruby编写的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 => 'mailto@example.com',
        :source => 'mailfrom@example.com',
      )
    end
  end
  sleep(1)
  pool.each(&:join)