Using Rails with Redis
I have met an issue recently that the Rails site always returns 502 error for some page. After some investigation, I have found that the problem is caused by a long time query of database, which exceeds the timeout value of unicorn configuration, then the unicorn worker process will be killed and the Nginx returns 502 to user.
So the solution for this kind prblem is to put the job into some background task, and use some other method to inform the frontend when job done. Finally I choose the Redis for this task.
First of all, the Redis server should be run on the server, I am using ubuntu on the server so the command is:
sudo apt-get install redis-server
After installion done, the server will be started as service in the server.
Then the Rails part. I am using a gem called
resque
for creating background jobs. I
have followed the RailsCasts #271
to setup my project, and here is a brief instruction for Rails part:
First a rake task for resque it is needed, which is also listed in the rails casts site.
require "resque/tasks"
task "resque:setup" => :environment
Then create workers for the long time tasks in app/worker
directory. I am
using sleep
method to simulate the long time task, and then the script will
write some data into Rails cache. Here is the file content of
app/worker/cache_writer.rb
class CacheWriter
@queue = :rails_cache
def self.perform(cache_key)
sleep 10
Rails.cache.write(cache_key, "foobar")
end
end
After worker creation done, I need to update code in the controller to enqueue
job to Redis. Now in the controller, I just need to enque the task to Redis
queue with Resque.enqueue
and return:
class TestCachesController < ApplicationController
def index
@foo = Rails.cache.read("foo")
if @foo.nil?
Resque.enqueue(CacheWriter, "foo")
end
end
def show
end
end
Now the task can be added to the queue, and we need worker to handle it. The
bin/resque work
will start a worker process, and the parameter --queues=
or --queue=
can be added to specify the working queue. I have copied some
code from this page to make the rake
can start/stop the workers.