11

我们的电子邮件无法使用带有 Redis 队列的 Laravel 发送。

触发错误的代码是这样的:->onQueue('emails')

$job = (new SendNewEmail($sender, $recipients))->onQueue('emails');
$job_result = $this->dispatch($job);

结合工作中的这一点:

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 时,它会欺骗电子邮件发送。我已经和 Sendgrid 谈过了,当我发生错误时,电子邮件从未接触过他们的服务器,而且他们的服务完全处于活动状态。所以,错误似乎在我的尽头。

有什么想法吗?

4

8 回答 8

27

似乎只有Mailtrap 会发送此错误,因此请打开另一个帐户或升级到付费计划。

于 2017-03-04T00:22:50.503 回答
10

我终于想出了如何设置整个 Laravel 应用程序以根据配置限制邮件。

boot()函数中AppServiceProvider

$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

唯一的问题是它似乎不会影响通过later()if 函数发送的邮件QUEUE_DRIVER=sync

于 2018-12-14T16:13:01.937 回答
7

仅用于调试!
如果您不希望收到超过 5 封电子邮件并且没有更改mailtrap的选项,请尝试:

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
    }
}

使用sleep()是一种非常糟糕的做法。理论上,这段代码应该只在测试环境或调试模式下执行。

于 2018-01-02T16:47:00.107 回答
3

也许您应该确保它确实是通过 Sendgrid 而不是 mailtrap 发送的。他们的硬速率限制目前似乎是每秒 3k 请求,而免费计划中的 mailtrap 每秒请求 3 :)

于 2017-06-01T14:21:48.550 回答
1

I used sleep(5) to wait five seconds before using mailtrap again.

foreach ($this->suscriptores as $suscriptor)  {
    \Mail::to($suscriptor->email)
           ->send(new BoletinMail($suscriptor, $sermones, $entradas));
    sleep(5);
}

I used the sleep(5) inside a foreach. The foreach traverses all emails stored in the database and the sleep(5) halts the loop for five seconds before continue with the next email.

于 2019-10-16T16:27:07.413 回答
1

我通过手动设置身份验证路由在 Laravel v5.8 上实现了这一点。路线位于文件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');
});

解释:

  • 不要将任何参数传递给路由Auth::routes();以手动配置身份验证路由。
  • 用中间件将路由包裹email/resend在 a中(这两个数字代表最大重试次数和这些最大重试次数的分钟数)Route::groupthrottle:1,1

我还在函数中删除了文件app\Http\Controllers\Auth\VerificationController.php中的一行代码__construct

我删除了这个:

$this->middleware('throttle:6,1')->only('verify', 'resend');
于 2019-05-28T03:07:08.310 回答
0

我在使用邮件陷阱时遇到了这个问题。我在一秒钟内发送了 10 封邮件,它被视为垃圾邮件。我不得不在每项工作之间进行延迟。看看解决方案(它的 Laravel - 我有system_jobs桌子和使用queue=database

制作一个静态函数来检查最后一个作业时间,然后添加到它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;
        }

    }

然后用它来延迟发送消息(考虑到队列中的最后一个作业)

Mail::to($mail)->later(SystemJobs::addSecondsToQueue(), new SendMailable($params));
于 2020-02-05T15:57:37.273 回答
0

You need to rate limit emails queue.

The "official" way is to setup Redis queue driver. But it's hard and time consuming.

So I wrote custom queue worker mxl/laravel-queue-rate-limit that uses Illuminate\Cache\RateLimiter to rate limit job execution (the same one that used internally by Laravel to rate limit HTTP requests).

In config/queue.php specify rate limit for emails queue (for example 2 emails per second):

'rateLimit' => [
    'emails' => [
        'allows' => 2,
        'every' => 1
    ]
]

And run worker for this queue:

$ php artisan queue:work --queue emails
于 2019-08-02T15:59:25.530 回答