【问题标题】:Heroku timeout when sending emails发送电子邮件时 Heroku 超时
【发布时间】:2015-11-25 21:54:07
【问题描述】:

我在 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 which one are you using
  #Supported enignes: [:solr,:sphinx]
  config.search_enabled = false
  config.search_engine = :sphinx
end

【问题讨论】:

    标签: ruby-on-rails heroku redis


    【解决方案1】:

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

    1. gem 'sidekiq' 添加到您的gemfile 并运行bundle
    2. 创建一个工作文件app/workers/message_worker.rb
    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. 更新您的控制器以使 Worker 排队

    删除: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 插件。

    【讨论】:

      【解决方案2】:

      听起来像是 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的sn-p:

      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等邮件递送服务。

      【讨论】:

        【解决方案3】:

        Sidekiq 是您可以考虑的一个选项。为了让它工作,你可以添加 RedisToGo 之类的东西,然后为 Redis 配置一个初始化程序。然后在 Heroku 上,您可以将 worker: bundle exec sidekiq ... 之类的内容添加到您的 Procfile 中。

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

        它还有一个用于监控的仪表板。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-10
          • 2011-08-23
          相关资源
          最近更新 更多