【问题标题】:500 Internal Server Error when sending email notification发送电子邮件通知时出现 500 内部服务器错误
【发布时间】:2015-08-16 08:01:27
【问题描述】:

我在 Heroku 上使用 Mailboxer gem,并正在尝试为消息设置电子邮件通知。

消息已创建,但在尝试通过电子邮件通知联系收件人时超时。

消息控制器:

  def create
    @recipient = User.find(params[:user])
    current_user.send_message(@recipient, params[:body], params[:subject])
    flash[:notice] = "Message has been sent!"
    if request.xhr?
        render :json => {:notice => flash[:notice]}
    else
        redirect_to :conversations
    end
  end

邮箱.rb:

Mailboxer.setup do |config|

  #Configures if you applications uses or no the email sending for Notifications and Messages
  config.uses_emails = true

  #Configures the default from for the email sent for Messages and Notifications of Mailboxer
  config.default_from = "no-reply@domain.com"

  #Configures the methods needed by mailboxer
  config.email_method = :mailboxer_email
  config.name_method = :name

  #Configures if you use or not a search engine and wich one are you using
  #Supported enignes: [:solr,:sphinx]
  config.search_enabled = false
  config.search_engine = :sphinx
end

用户模型:

def mailboxer_email(object)
    if self.no_email
      email
    else
        nil
    end
end

Production.rb:

  config.action_mailer.delivery_method = :smtp
  config.action_mailer.default_url_options = { :host => 'domain.herokuapp.com' }
  config.action_mailer.smtp_settings = {
    address:              'smtp.gmail.com',
    port:                 587,
    domain:               'gmail.com',
    user_name:            'username@gmail.com',
    password:             'password',
    authentication:       'plain',
    enable_starttls_auto: false  }

  config.action_mailer.default_url_options = { :host => "domain.herokuapp.com" }

    config.action_mailer.perform_deliveries = true

日志:

Aug 14 12:11:23 domain app/web.1:    Parameters: {"utf8"=>"✓", "user"=>"7", "subject"=>"inhereyes messaged you", "body"=>"Will the email send this time as notification?", "commit"=>"Send"} 
Aug 14 12:11:23 domain app/web.1:    Rendered vendor/bundle/ruby/2.0.0/gems/mailboxer-0.11.0/app/views/message_mailer/new_message_email.html.erb (0.6ms) 
Aug 14 12:11:23 domain app/web.1:    Rendered vendor/bundle/ruby/2.0.0/gems/mailboxer-0.11.0/app/views/message_mailer/new_message_email.html.erb (0.6ms) 
Aug 14 12:11:23 domain app/web.1:    Rendered vendor/bundle/ruby/2.0.0/gems/mailboxer-0.11.0/app/views/message_mailer/new_message_email.text.erb (0.2ms) 
Aug 14 12:11:23 domain app/web.1:    Rendered vendor/bundle/ruby/2.0.0/gems/mailboxer-0.11.0/app/views/message_mailer/new_message_email.text.erb (0.2ms) 
Aug 14 12:11:52 domain heroku/router:  at=error code=H12 desc="Request timeout" method=POST path="/messages" host=domain.com request_id=b00e5acf-3342-4e80-913e-610c5be6d83c fwd="73.54.214.248,108.162.237.126" dyno=web.1 connect=0ms service=30001ms status=503 bytes=0 
Aug 14 12:12:23 domain app/web.1:  Sent mail to email@hotmail.com (60151.4ms) 
Aug 14 12:12:23 domain app/web.1:  Sent mail to email@hotmail.com (60151.4ms) 
Aug 14 12:12:23 domain app/web.1:  Completed 500 Internal Server Error in 60210ms 
Aug 14 12:12:23 domain app/web.1:  Completed 500 Internal Server Error in 60210ms 
Aug 14 12:12:23 domain app/web.1:  Net::ReadTimeout (Net::ReadTimeout): 
Aug 14 12:12:23 domain app/web.1:    app/controllers/messages_controller.rb:15:in `create' 
Aug 14 12:12:23 domain app/web.1:    app/controllers/application_controller.rb:27:in `user_time_zone' 
Aug 14 12:12:23 domain app/web.1:  Net::ReadTimeout (Net::ReadTimeout): 
Aug 14 12:12:23 domain app/web.1:    app/controllers/messages_controller.rb:15:in `create' 
Aug 14 12:12:23 domain app/web.1:    app/controllers/application_controller.rb:27:in `user_time_zone'

【问题讨论】:

  • 我认为这只是 Heroku 在 30 秒后超时,您的请求持续多长时间?

标签: ruby-on-rails heroku


【解决方案1】:

这里指出您的电子邮件生成大约需要 60 秒,如果我没记错的话,Heroku 会在 30 秒后超时。

Aug 14 12:12:23 domain app/web.1:  Sent mail to email@hotmail.com (60151.4ms) 
Aug 14 12:12:23 domain app/web.1:  Sent mail to email@hotmail.com (60151.4ms)

【讨论】:

  • 所以唯一的解决办法是运行一个后台任务,这样它就不会超时 heroku?
  • 对,或者让您的电子邮件生成速度更快。我不知道为什么需要这么长时间。
  • 在 Rails 4 中,使用 Deliver_later 发送带有后台作业的电子邮件要容易得多。不过,在 Heroku 中,这意味着您必须为测功机付费。
  • 我认为您可以在新的免费帐户上拥有多个测功机。 blog.heroku.com/archives/2015/5/7/heroku-free-dynos
  • @thedanotto:是的,他们最近改变了一些事情。那么很好的变化。
【解决方案2】:

要使用 Gmail,您需要确保它可以绕过 Google 的现代安全协议。

虽然我可以解释如何操作,但我建议使用 Mandrill、Sendgrid、Mailjet 或其他电子邮件程序,因为 Gmail 每天最多只能向 500 位收件人发送电子邮件。

就个人而言,我使用 Mandrill,并且喜欢在 RoR 之外设置电子邮件模板、运行 A-B 测试以及跟踪谁打开/查看电子邮件的能力。

【讨论】:

  • 感谢您的建议。起初我实际上是在使用我的服务器托管,但我只是切换到 gmail,因为两者都不起作用。问题似乎是控制器。当应用程序变大时,我会记住 mandrill。
【解决方案3】:

它说你在 messages_controller.rb 第 15 行有错误

app/controllers/messages_controller.rb:15

【讨论】:

  • current_user.send_message(@recipient, params[:body], params[:subject])