HerokuからAWSへの移行(SESの罠編)
初めに
初めまして!
皆様どうもこんばんわ、こんにちわ、おはようございます。
エンジニアの榎本です。
最近、Heroku で運用していた Rails アプリケーションを AWS に移行しました。
その中で SendGrid → Amazon SES の乗り換えで思わぬ落とし穴にハマったので、同じ道を通る方の助けになればと記事にまとめます。
この記事が参考になる方
・Heroku から AWS への移行を検討している
・SendGrid から Amazon SES への移行を検討している
・メールを一斉送信するワークロードを持っている
何が罠なの?
罠ってなんやねんと思う方もいると思いますので、説明しておくと、、、
今回HerokuからAWSへの移行にあたり、SendGridから、SESへの移行をしました。
移行作業を行なっている途中で、あれ、Sidekiqの管理画面を見ると、なんかmailの送信失敗している??ということに気づきました。
Net::SMTPFatalError
Sidekiq/ActionMailer::MailDeliveryJob
Level: Error
554 Transaction failed: Recipient count exceeds 50.
ファ。。?
実はSESでは1回の送信処理における最大宛先件数に50件という制限があり、50件以上の場合、送信できないということがありました。
下記が公式ドキュメント
今回移行したアプリケーションでは、一度に送る宛先の件数が50件以上あったため、引っかかっていました。
対処法
1.Service Quotasの制限の引き上げを依頼する
2.アプリケーション側を変更し、一度に送信するメールの宛先が50件を超えないようにする
今回移行作業中に起こったということもあり、1の対処法はいつ申請が通るかわからない(多分そんなに時間はかからない)&宛先が何件に膨れるかわからないということで、2の対処にしました。
以下のような感じで50件ずつ送信することにしました
rubyだとeach_sliceなんかが使えます
#変更前
bcc_users = [xxx]
mail(bcc: bcc_users, subject: 'test')
#変更後
bcc_users = [xxx]
bcc_users.each_slice(50) do |recipients_slice| # SESの送信制限に合わせて50人ずつに
mail(bcc: recipients_slice, subject: 'test')
end
アプリケーションコードを高速で修正し、デプロイし直して、再度その処理を走らせると成功しました。
Sidekiqのretry処理に助けられました。
教訓
・AWS にはサービスごとにいろんなのクオータの制限が存在する(例:SQS メッセージサイズ、Lambda 同時実行数、ECS タスク数 etc.)
・移行計画では 依存サービスのクオータをちらっとでも確認しておくと良いかも。
Discussion