我有一个在线软件,可以向Amazon SES发送电子邮件。目前我有一个cron作业,通过SMTP发送电子邮件与phpmailer发送消息。目前我必须将发送限制最大限制为每分钟300左右,以确保我的服务器没有超时。我们看到增长,最终我想发送到10,000或更多。
是否有更好的方式发送到Amazon SES,或者这是其他所有人的做法,但只有更多服务器运行工作负载?
提前致谢!
答案 0 :(得分:7)
您可以尝试使用AWS SDK for PHP。您可以通过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
and friends来提高其效率。
您需要对此代码进行微调,但可能能够实现更高的电子邮件吞吐量。
答案 1 :(得分:0)
感谢您的回答。这是一个很好的起点。 @Jeremy Lindblom
我现在的问题是我无法使错误处理工作。 catch() - Block正常工作
$successfulCommands
使用状态代码返回所有成功响应,但仅在发生错误时返回。例如沙箱模式中的“未验证地址”。像catch()应该工作。 :)
try-Block中的 $ successfulCommands 仅返回:
SplQueue Object
(
[flags:SplDoublyLinkedList:private] => 1
[dllist:SplDoublyLinkedList:private] => Array
(
)
)
我无法弄清楚如何通过状态码等获取亚马逊的真实响应。
答案 2 :(得分:0)
如果有人正在寻找这个答案,那么它过时了,您可以在此处找到新文档: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命令可以做同样的事情