PHP 向 Amazon SES 发送大量电子邮件


PHP Sending Large Amounts of Email to Amazon SES

我有一个向 Amazon SES 发送电子邮件的在线软件。目前我有一个cron作业,它通过SMTP和phpmailer发送电子邮件来发送消息。目前,我必须将发送限制最大化到每分钟300左右,以确保我的服务器不会超时。我们看到了增长,最终我想发送10,000或更多。

是否有更好的方法发送到 Amazon SES,或者这是其他人所做的,但只有更多服务器运行工作负载?

提前感谢!

您可以尝试使用适用于 PHP 的 AWS 开发工具包。您可以通过 SES API 发送电子邮件,SDK 允许您并行发送多封电子邮件。下面是一个代码示例(未经测试,仅部分完成)可帮助您入门。

<?php
require 'vendor/autoload.php';
use Aws'Ses'SesClient;
use Guzzle'Service'Exception'CommandTransferException;
$ses = SesClient::factory(/* ...credentials... */);
$emails = array();
// @TODO SOME SORT OF LOGIC THAT POPULATES THE ABOVE ARRAY
$emailBatch = new SplQueue();
$emailBatch->setIteratorMode(SplQueue::IT_MODE_DELETE);
while ($emails) {
    // Generate SendEmail commands to batch
    foreach ($emails as $email) {
        $emailCommand = $ses->getCommand('SendEmail', array(
            // GENERATE COMMAND PARAMS FROM THE $email DATA
        ));
        $emailBatch->enqueue($emailCommand);
    }
    try {
        // Send the batch
        $successfulCommands = $ses->execute(iterator_to_array($emailBatch));
    } catch (CommandTransferException $e) {
        $successfulCommands = $e->getSuccessfulCommands();
        // Requeue failed commands
        foreach ($e->getFailedCommands() as $failedCommand) {
            $emailBatch->enqueue($failedCommand);
        }
    }
    foreach ($successfulCommands as $command) {
        echo 'Sent message: ' . $command->getResult()->get('MessageId') . "'n";
    }
}
// Also Licensed under version 2.0 of the Apache License.

你也可以考虑使用Guzzle BatchBuilder和朋友来使其更健壮。

您需要对此代码进行很多微调,但您可以实现更高的电子邮件吞吐量。

如果有人正在寻找这个答案,它已经过时了,你可以在这里找到新的文档:https://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/commands.html

use Aws'S3'S3Client;
use Aws'CommandPool;
// Create the client.
$client = new S3Client([
    'region'  => 'us-standard',
    'version' => '2006-03-01'
]);
$bucket = 'example';
$commands = [
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'a']),
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'b']),
    $client->getCommand('HeadObject', ['Bucket' => $bucket, 'Key' => 'c'])
];
$pool = new CommandPool($client, $commands);
// Initiate the pool transfers
$promise = $pool->promise();
// Force the pool to complete synchronously
$promise->wait();

SES 命令也可以做同样的事情

谢谢你的回答。这是一个很好的起点。@Jeremy 林德布洛姆

我的问题是现在我无法让错误处理工作。catch()-block 工作正常,在它里面

$successfulCommands
返回

所有带有状态代码的成功响应,但仅在发生错误时返回。例如沙盒模式下的"未经验证的地址"。就像一个 catch() 应该工作。:)

try-Block 内的$successfulCommands仅返回:

SplQueue Object
(
    [flags:SplDoublyLinkedList:private] => 1
    [dllist:SplDoublyLinkedList:private] => Array
    (
    )
)

我不知道如何使用状态代码等从亚马逊获得真正的响应。