Heroku + Redis + Resque + ActiveJobで手軽に無料でバックグラウンド処理
概要
-
- 2015/05のHerokuの料金体制改定で、Freeプランでもworker dynoが使えるようになった。
-
- さらに、2015.06にはHeroku Redisが一般公開された。25MBまでなら無料で使える。
- Rails 4.2で追加されたActiveJobの機構を使って、シンプルに、効率的に無料でHeroku上でバックグランド処理を実装できるようになった。
背景资料
Heroku – 应用部署平台 for applications.
-
- Herokuにはweb dynoとworker dynoがある。
HTTPリクエストを処理するのがweb dyno
バックグランドで処理をするのがworker dyno
元々の無料プランではweb dynoの追加には料金がかかったが、新しい無料プランでは制限付きながらworker dynoが使えるようになった。実験するには、それでも十分。
Heroku上でバックグランド処理をやる仕組みとしてはDelayed Jobというものが用意されていたが、 DBの負荷的な問題から現在は使用が推奨されていない。
代わりにRedisベースのキューイングライブラリの使用が推奨されている。(Resqueなど)
Redis和Resque
Resque调度器
-
- Resque単体では、キューに積まれたジョブを順次実行していくことしかできないが、Resque Schedulerを使うと、任意のタイミングでジョブを実行できるようになる。
-
- 具体的には、「数日後にメールを送りたい」というようなジョブのスケジューリングが可能になる。
- ややこしくなるため、Resque Schedulerの説明はここでは割愛。
主动工作
-
- Rails 4.2で登場した、バックグラウンドジョブの実行機構。
- Delayed JobとResqueなどのように、さまざまなジョブ実行機能のAPIの違いを気にせずにバックグラウンドジョブの実装を記述できる。
步骤
-
- 搭建开发环境
-
- 设置Heroku
-
- 在本地运行
- 在Heroku上进行操作确认
開発環境のセットアップ
安装Redis
brew install redis
根据需要进行自动启动配置(在安装后的消息中显示)。
开发时
Resque的配置
添加宝石
gem 'resque'
只需添加 gem 就可以了。添加后执行 bundle install。
Resque的配置
Resque.redis = Redis.new(:url => ENV['REDIS_URL'])
Resque.after_fork = Proc.new { ActiveRecord::Base.establish_connection }
创建一个名为config/initializers/resque.rb的初始化器,来配置Redis的连接设置,以及在作业中使用ActiveRecord的设置。
在使用Rails从Heroku Redis中使用Redis时,您需要在url中指定ENV[‘REDIS_URL’]。(https://devcenter.heroku.com/articles/heroku-redis#connecting-in-ruby)
环境变量REDIS_URL会在添加Heroku Redis附加组件时设置。当然,如果在本地运行,则url将为空,因此如果Redis服务器在默认位置之外运行,则需要另外指定。
在fork后,执行ActiveRecord::Base.establish_connection来设置使得ActiveRecord可以被使用。
将ActiveJob配置为使用Resque
ActiveJob::Base.queue_adapter = :resque
同样地,创建一个针对ActiveJob的初始化方法,其中将queue_adapter设为:resque。
添加用于启动Resque的任务
require 'resque/tasks'
启动Resque
TERM_CHILD=1 QUEUES=* rake environment resque:work
如果不加上TERM_CHILD=1,则会显示警告:This way of doing signal handling is now deprecated. 这是因为在Resque的原始实现中,存在问题,当收到结束进程的信号时。由于兼容性问题,默认行为仍然保持旧规范,但是目前该规范已被弃用,因此会显示此消息。如果添加TERM_CHILD=1,则会得到一般的、与其他程序相同的退出行为,并且警告也会消失。
实施
创建一个Job类
rails g job my_job
class MyJob < ActiveJob::Base
queue_as :default
def perform(instance)
p "Process #{instance}"
end
end
将非同步处理排入队列中
MyJob.perform_later(instance)
Herokuの設定
Heroku Redisの追加
https://elements.heroku.com/addons/heroku-redis からプランを選択して追加する。25MBまでなら無料のHobbyプランが使える。Hobbyプランでは永続化はできないが、Resqueで使う分には大きな問題はない。(Redisが再起動した時にその時のキューの内容が消えてしまうという問題はあるかもしれない)
工人使用工作流程的设置
worker: TERM_CHILD=1 QUEUES=* rake environment resque:work
将Resque的Rake任务配置为worker来启动。
激活工人

最后,通过激活仪表板上的Worker功能来完成。
总之
由于Heroku的计划改革、Heroku Redis的引入以及Active Job的出现,在Heroku上实施背景处理变得非常容易。让我们不断利用它。
请参考下面的链接。
请参考以下连接。
请参照如下链接。
-
- http://blog.flect.co.jp/labo/2015/05/free-dyno-fae3.html
-
- https://devcenter.heroku.com/articles/delayed-job
-
- https://blog.engineyard.com/2014/getting-started-with-active-job
- http://qiita.com/Takayuki-Suzuki@github/items/cf2f904873496ff6c384