Heroku在发送电子邮件时超时

时间:2015-08-31 19:20:25

标签: ruby-on-rails heroku redis

我在Heroku上使用自定义域名,我有Redis附加组件。我需要帮助了解如何为电子邮件通知创建后台工作程序。用户可以互相收件箱,我希望向用户发送收到的每封新邮件的电子邮件通知。我有开发工作的通知,但我不擅长创建Heroku所需的后台作业,否则服务器会超时。

消息控制器:

  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

用户模型:

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

Mailboxer.rb:

Mailboxer.setup do |config|

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

  #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

3 个答案:

答案 0 :(得分:7)

Sidekiq绝对是Heroku的选择。我不认为邮箱支持开箱即用的后台配置。值得庆幸的是,使用sidekiq的排队过程仍然非常容易。

  1. gem 'sidekiq'添加到您的gemfile并运行bundle
  2. 创建工作文件app/workers/message_worker.rb
  3. class MessageWorker
      include Sidekiq::Worker
    
      def perform(sender_id, recipient_id, body, subject)
        sender = User.find(sender_id)
        recipient = User.find(recipient_id)
        sender.send_message(recipient, body, subject) 
      end
    end
    
    1. 更新您的控制器以排队工作人员
    2. 删除:current_user.send_message(@recipient, params[:body], params[:subject])

      添加:MessageWorker.perform_async(current_user.id, @recipient.id, params[:body], params[:subject])

      注意:您永远不应该传递工作者ActiveRecord对象。这就是为什么我设置此方法来传递用户ID并在工作人员perform方法中查找它们而不是整个对象的原因。

      1. 最后,重启服务器并运行bundle exec sidekiq。现在您的应用应该发送电子邮件背景。

      2. 部署时,您需要为工作人员设置一个单独的dyno,如下所示:worker: bundle exec sidekiq。您还需要Heroku的redis插件。

答案 1 :(得分:5)

听起来像H21请求超时:

  

HTTP请求的完成时间超过30秒。

要在RoR中为此创建后台工作程序,您应该获取Resque,一个Redis支持的RoR背景排队库。 Here is a demoAnother demoAnd another demo.

要了解有关在Heroku中使用Resque的更多信息,请you can also read the herokue article up hereOr this tutorial (it's an old one though)Another great tutorial

还有一个resque_mailer gem可以帮助您加快速度。

gem install resque_mailer #or add it to your Gemfile & use bundler 

这很简单。以下是a working demo by the author的摘录:

class Notifier < ActionMailer::Base
  include Resque::Mailer

  default :from => "from@example.com"

  def test(data={})
    data.symbolize_keys!

    Rails.logger.info "sending test mail"
    Rails.logger.info "params: #{data.keys.join(',')}"
    Rails.logger.info ""

    @subject = data[:subject] || "Testing mail"
    mail(:to => "nap@localhost.local",
         :subject => @subject)
  end
end

执行Notifier.test.deliver将传递邮件。

您还可以考虑使用SES等邮件投放服务。

答案 2 :(得分:1)

Sidekiq是您可以考虑的选项。要使其正常工作,您可以添加类似RedisToGo的内容,然后为Redis配置初始化程序。然后在Heroku上,您可以在Procfile中添加类似worker: bundle exec sidekiq ...的内容。

https://github.com/mperham/sidekiq/wiki/Getting-Started

它还有一个监控仪表板。

https://github.com/mperham/sidekiq/wiki/Monitoring