You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails使用AWS SES发送数千封邮件时应用离线(错误码524)

问题分析与解决方案

问题根源

524是Cloudflare的超时错误,触发原因是你的Rails请求主线程同步执行数千封邮件发送操作,耗时远超Cloudflare默认的100秒响应阈值,导致请求被中断;同时同步循环长时间占用应用线程,使得应用无法处理其他请求,最终引发离线。此外当前实现还有两个额外性能问题:

  • 每次发送邮件都新建Aws::SES::Client实例,重复建立连接增加资源开销
  • 逐个调用send_email接口,API调用次数过多效率低下

解决方案

1. 改用异步任务处理(核心修复)

把邮件发送逻辑从请求主线程移到后台异步任务,避免阻塞请求。Rails自带的Active Job结合Sidekiq/Resque即可实现:

步骤1:生成异步Job

rails generate job SendBulkEmail

步骤2:编写Job代码(复用SES客户端+批量发送)

# app/jobs/send_bulk_email_job.rb
class SendBulkEmailJob < ApplicationJob
  queue_as :default

  def perform(email_list, subject, html_body)
    # 复用SES客户端,避免重复建立连接
    ses_client = Aws::SES::Client.new(region: 'ap-west-1')
    sender = 'hello@example.com'
    encoding = 'UTF-8'
    text_body = "This email was sent with Amazon SES using the AWS SDK for Ruby."

    # 拆分邮箱列表为小批量(根据SES发送配额调整,比如50个/批)
    email_list.each_slice(50) do |batch|
      begin
        # 使用SES批量发送接口,减少API调用次数
        response = ses_client.send_bulk_email({
          source: sender,
          destinations: batch.map { |email| { to_addresses: [email] } },
          message: {
            subject: { charset: encoding, data: subject },
            body: {
              html: { charset: encoding, data: html_body },
              text: { charset: encoding, data: text_body }
            }
          }
        })

        # 记录失败的收件人,后续重试
        failed_emails = response.failed_recipients.map(&:email_address)
        SendBulkEmailJob.perform_later(failed_emails, subject, html_body) if failed_emails.any?
      rescue Aws::SES::Errors::ServiceError => e
        Rails.logger.error "批量邮件发送失败:#{e.message}"
        # 可选:将整个批次重新加入队列重试
        SendBulkEmailJob.perform_later(batch, subject, html_body)
      end

      # 速率控制:避免超过SES发送配额,根据你的配额调整间隔
      sleep 1
    end
  end
end

步骤3:在控制器中触发异步任务

# 控制器中的处理逻辑
def trigger_bulk_email
  @emails = ['abc@gmail.com', 'abc@example.com'] # 数千个邮箱
  SendBulkEmailJob.perform_later(@emails, @email_subject, @email_body_html)
  
  redirect_to your_path, notice: "批量邮件任务已启动,后台将自动处理"
end

2. 配置异步任务适配器

以Sidekiq为例:

  1. 添加Gem到Gemfile:
gem 'sidekiq'
  1. 安装并配置:
bundle install
  1. 修改config/application.rb:
config.active_job.queue_adapter = :sidekiq
  1. 启动Sidekiq进程处理队列:
bundle exec sidekiq

3. 额外优化建议

  • 检查SES配额:在AWS控制台查看SES的发送速率限制和每日配额,调整批量大小和间隔,避免被限流
  • 添加日志监控:记录邮件发送状态,方便排查失败原因
  • 使用模板邮件:如果邮件内容固定,改用SES的模板邮件接口(send_templated_email/send_bulk_templated_email),进一步提升效率

内容的提问来源于stack exchange,提问作者user9769384

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 16:06:28