ActionMailer + DelayedJob + Resque + SendGrid = 并非所有电子邮件都已发送

ActionMailer + DelayedJob + Resque + SendGrid = not all emails being sent

我在 Heroku 上有一个 Rails 4.2.5 应用程序,使用 ActionMailer、SendGrid 和 DelayedJob/Resque 进行后台处理。我遇到了一个无法在本地主机上重现的 st运行ge 问题。

我发了一批邮件。没有出现错误,因此电子邮件似乎已成功发送。然后我检查 SendGrid 的 activity 选项卡,只看到那里的一半电子邮件。

我没有对 SendGrid 或 ActionMailer 做过很多工作,所以我不太确定如何调试问题或在本地重现问题。我尝试通过在我的应用程序中创建 100 contacts 然后向它​​们发送相同的通知消息(就像在生产应用程序中会发生的一样)来进行复制,但它们都成功通过了。

development.rbproduction.rb我有:

config.action_mailer.raise_delivery_errors = true

production.rb我有:

config.action_mailer.default_url_options = { :host => 'http://firmplay.com' }
# config.action_mailer.delivery_method = :sendmail
# config.action_mailer.sendmail_settings = {
#   :location => '/usr/sbin/sendmail',
#   :arguments => '-i -t'
# }

# config.action_mailer.perform_deliveries = true
# config.action_mailer.raise_delivery_errors = true

我不确定注释的代码是否应该取消注释。

environment.rb我有:

ActionMailer::Base.smtp_settings = {
  :address        => 'smtp.sendgrid.net',
  :port           => '587',
  :authentication => :plain,
  :user_name      => ENV['SENDGRID_USERNAME'],
  :password       => ENV['SENDGRID_PASSWORD'],
  :domain         => 'heroku.com',
  :enable_starttls_auto => true
}

application.rb我有:

config.active_job.queue_adapter = :resque

我不确定我在这里做错了什么,甚至不确定问题是什么时候开始的,尽管我怀疑这与我最近从 Rails 4.0 升级到 4.2.5 有关。我想知道电子​​邮件是否在 DelayedJob/Resque 中的某个地方失败了,所以我检查了 Resque 日志,没有发现任何异常。

更新部分解决方案

虽然我在解决这个问题上取得了一些进展。当我在生产环境中进行测试时,我意识到当使用我的 web dyno 将电子邮件作为后台作业排队时,它会在 10 秒后超时,这是应用程序的限制。即使在 web worker 超时之后,它仍会继续排队电子邮件,直到 运行 内存不足(在日志中看到一些 R14 错误)。

我无法确定为什么在排队电子邮件时 运行 内存不足。我没有将电子邮件作为变量存储在内存中,但我想它们可能是在我遍历联系人列表时无意中存储的。

我最后做的是创建一个后台作业,我可以将联系人列表传递给它。然后后台作业直接发送电子邮件。当我测试这种方法时,一切都很好,而且扩展得很好。所以从本质上讲,我的问题已经解决了,尽管我仍然想找出为什么 web dyno 在排队电子邮件时 运行 内存不足,而后台工作人员 运行 Resque 却没有任何此类问题。

我最初使用 .map 遍历我的联系人,它将每个循环中返回的最后一个项目存储在内存中。我转而使用 .each,以为这样可以解决问题,但事实并非如此。无论如何,问题似乎是 Ruby 在控制器的生命周期内将电子邮件存储在内存中。

您的问题来源似乎在 this Heroku article 中得到处理。