【发布时间】:2016-08-29 05:38:18
【问题描述】:
我在 Heroku 上有一个 Rails 4.2.5 应用程序,使用 ActionMailer、SendGrid 和 DelayedJob/Resque 进行后台处理。我有一个奇怪的问题,我无法在 localhost 上重现。
我发送了一批电子邮件。没有出现错误,因此电子邮件似乎已成功发送。然后我检查 SendGrid 的活动选项卡,在那里只看到一半的电子邮件。
我对 SendGrid 或 ActionMailer 所做的工作不多,所以我不太确定如何调试问题或在本地重现问题。我尝试通过在我的应用程序中创建 100 contacts 然后向它们发送相同的通知消息来进行复制(就像在生产应用程序中发生的那样),但它们都成功地通过了。
在development.rb 和production.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 在控制器的生命周期内将电子邮件存储在内存中。
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-4 actionmailer delayed-job sendgrid