Php Laravel电子邮件队列550错误(每秒电子邮件太多)
我们的电子邮件无法使用带有Redis队列的Laravel发送 触发错误的代码如下:Php Laravel电子邮件队列550错误(每秒电子邮件太多),php,laravel,smtp,swiftmailer,laravel-forge,Php,Laravel,Smtp,Swiftmailer,Laravel Forge,我们的电子邮件无法使用带有Redis队列的Laravel发送 触发错误的代码如下:->onQueue('emails') 结合工作中的这一点: use InteractsWithQueue; 我们的错误消息是: Feb 09 17:15:57 laravel: message repeated 7947 times: [ production.ERROR: exception 'Swift_TransportException' with message 'Expected response
->onQueue('emails')
结合工作中的这一点:
use InteractsWithQueue;
我们的错误消息是:
Feb 09 17:15:57 laravel: message repeated 7947 times: [ production.ERROR: exception 'Swift_TransportException' with message 'Expected response code 354 but got code "550", with message "550 5.7.0 Requested action not taken: too many emails per second "' in /home/laravel/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php:383 Stack trace: #0 /home/laravel/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php(281):
我们的错误只发生在使用Sendgrid而不是Mailtrap时,Mailtrap欺骗了电子邮件发送。我已经和Sendgrid谈过了,当我的错误发生时,这些电子邮件从未接触过他们的服务器,他们的服务也完全处于活动状态。因此,错误似乎在我这边
有什么想法吗?似乎只是发送了这个错误,所以要么打开另一个帐户,要么升级到付费计划。也许你应该确保它确实是通过Sendgrid发送的,而不是mailtrap。他们的硬速率限制目前似乎是每秒3k个请求,而免费计划中的mailtrap每秒3个请求:)仅用于调试
如果您不希望收到超过5封电子邮件,并且没有更改邮件陷阱的选项,请尝试:
foreach ($emails as $email) {
...
Mail::send(... $email);
if(env('MAIL_HOST', false) == 'smtp.mailtrap.io'){
sleep(1); //use usleep(500000) for half a second or less
}
}
使用是一种非常糟糕的做法。理论上,这段代码应该只在测试环境或调试模式下执行。我终于想出了如何设置整个Laravel应用程序来根据配置限制邮件。 在AppServiceProvider的
boot()
函数中
$throttleRate = config('mail.throttleToMessagesPerMin');
if ($throttleRate) {
$throttlerPlugin = new \Swift_Plugins_ThrottlerPlugin($throttleRate, \Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE);
Mail::getSwiftMailer()->registerPlugin($throttlerPlugin);
}
在config/mail.php
中,添加以下行:
'throttleToMessagesPerMin' => env('MAIL_THROTTLE_TO_MESSAGES_PER_MIN', null), //https://mailtrap.io has a rate limit of 2 emails/sec per inbox, but consider being even more conservative.
在.env
文件中,添加一行,如:
MAIL_THROTTLE_TO_MESSAGES_PER_MIN=50
唯一的问题是,如果
QUEUE\u DRIVER=sync
我在Laravel v5.8上通过手动设置身份验证路由实现了这一点,那么它似乎不会影响通过later()函数发送的邮件。路由位于文件routes\web.php
中。以下是需要添加到该文件的路由:
Auth::routes();
Route::get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
Route::get('email/verify/{id}', 'Auth\VerificationController@verify')->name('verification.verify');
Route::group(['middleware' => 'throttle:1,1'], function(){
Route::get('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
});
说明:
$this->middleware('throttle:6,1')->only('verify', 'resend');
- 不要将任何参数传递给路由
Auth::routes()
允许手动配置身份验证路由
- 使用中间件
throttle:1,1
(这两个数字表示最大重试次数和这些最大重试次数的时间(以分钟为单位),将路由电子邮件/重发
包装在路由::组
中
我还删除了\u construct
函数中文件app\Http\Controllers\Auth\VerificationController.php
中的一行代码
我删除了这个:
$this->middleware('throttle:6,1')->only('verify', 'resend');
您需要对限制电子邮件队列进行评级
“官方”的方式是设置。但这既困难又耗时
因此,我编写了自定义队列工作程序,它使用illumb\Cache\RateLimiter
对作业执行进行分级限制(与Laravel to内部使用的相同)
在config/queue.php
中指定电子邮件的速率限制
队列(例如每秒2封电子邮件):
并为此队列运行worker:
$ php artisan queue:work --queue emails
我使用了sleep(5)
等待五秒钟,然后再次使用mailtrap
foreach($this->suscriptores作为$suscriptor){
\邮件::收件人($suscriptor->email)
->发送(新邮件($suscriptor,$sermones,$entradas));
睡眠(5);
}
我在foreach
中使用了sleep(5)
。foreach遍历数据库中存储的所有电子邮件,而睡眠(5)
会在继续下一封电子邮件之前暂停循环五秒钟。我在使用邮件陷阱时遇到了这个问题。我在一秒钟内发送了10封邮件,被当作垃圾邮件处理。我不得不在每项工作之间耽搁。看看解决方案(它的Laravel-我有系统作业
表,并使用队列=数据库
)
创建一个静态函数来检查上次作业时间,然后将其添加到self::DELAY_IN_SECONDS
-您希望在两次作业之间有多少秒:
public static function addSecondsToQueue() {
$job = SystemJobs::orderBy('available_at', 'desc')->first();
if($job) {
$now = Carbon::now()->timestamp;
$jobTimestamp = $job->available_at + self::DELAY_IN_SECONDS;
$result = $jobTimestamp - $now;
return $result;
} else {
return 0;
}
}
然后使用它来延迟发送消息(考虑队列中的最后一个作业)
这是邮件服务器的响应代码,因此如果您使用Sendgrid的服务器,则错误必须来自他们查看您尝试发送的电子邮件数量(7947)。我认为您应该查看Sendgrid的批量电子邮件选项。我们在我以前的工作中也遇到了同样的问题,我们最终使用MailChimp并使用他们的API来同步订户列表。我猜SendGrid可能会有相同的功能或类似的东西。它只有两封电子邮件。它一直试图重新发送8000次,因为它失败了。我正试图解决同样的问题。我想知道在Laravel中是否有一些我们可以启用的速率限制,比如在Node中:这里有一些东西需要我们探索:或者只是将邮件延迟10秒以上。我可能会弄错-但是Sendgrid不是用来发送邮件的吗?Mailtrap不用于发送邮件,而是用于捕获邮件以进行测试。因此,这并不能解决那些试图测试群发邮件的人的问题。这个答案解决了测试laravel 5.8验证代码时的问题。你把睡眠放在哪里了?如果你需要更高的粒度,你也可以使用\Swift\u Plugins\u ThrottlerPlugin::MESSAGES\u PER\u SECOND
public static function addSecondsToQueue() {
$job = SystemJobs::orderBy('available_at', 'desc')->first();
if($job) {
$now = Carbon::now()->timestamp;
$jobTimestamp = $job->available_at + self::DELAY_IN_SECONDS;
$result = $jobTimestamp - $now;
return $result;
} else {
return 0;
}
}
Mail::to($mail)->later(SystemJobs::addSecondsToQueue(), new SendMailable($params));