Professional Documents
Culture Documents
Setting up the workers is fairly easy, but pushing it to production becomes more
difficult, especially if you want to limit the overhead of managing the different
processes.
Eventually, I spent quite a lot of hours browsing the web looking for fixes to my
particular problems. This post synthesizes my findings by describing the final setup
and highlighting a few tricks.
Prerequisites
Before you go any further, you should already have Resque workers up and running.
The gem doc (https://github.com/defunkt/resque) is already pretty good, otherwise I
recommend this screencast by Ryan Bates (http://railscasts.com/episodes/271-resque)
and this article from Tanel Suurhans (http://www.perfectline.ee/blog/cron-tasks-
for-your-rails-application-with-resque). As for Redis if you’re new with it, Jim Neath
describes fairly well how to set it up and use it (http://jimneath.org/2011/03
/24/using-redis-with-ruby-on-rails.html).
Step 1: God
God is a process that makes sure that the processes it manages are up and running. If
they’re down for some reason, it restarts them. If you want to kill your processes, just
shut down God, it’ll do it for you. Very valuable when the only UI you have is a
command line.
Ben and the world (/) Next, we’ll create a daemon so that it runs automatically on startup. Since I’m using
RVM, I had to create a wrapper (https://rvm.io//integration/god/):
I use vim for editing but you can choose whatever you prefer. In this file, copy paste the
following:
#!/bin/bash ?
#
# god Startup script for god (<a href="http://god.rubyforge.org
#
# chkconfig: - 99 1
# description: God is an easy to configure, easy to extend monitoring \
# framework written in Ruby.
#
CONF_FILE=/opt/god/master.conf
DAEMON=/home/ben/.rvm/bin/boot_god
PIDFILE=/var/run/god.pid
LOGFILE=/var/log/god.log
SCRIPTNAME=/etc/init.d/god
#DEBUG_OPTIONS="--log-level debug"
DEBUG_OPTIONS=""
RETVAL=0
god_start() {
start_cmd="$DAEMON -l $LOGFILE -P $PIDFILE $DEBUG_OPTIONS -c $CONF_FIL
echo $start_cmd
$start_cmd || echo -en "god already running"
RETVAL=$?
return $RETVAL
}
god_stop() {
stop_cmd="$DAEMON terminate"
#stop_cmd="kill -QUIT `cat $PIDFILE`"
echo $stop_cmd
$stop_cmd || echo -en "god not running"
}
case "$1" in
start)
god_start
RETVAL=$?
;;
stop)
god_stop
RETVAL=$?
;;
restart)
god_stop
god_start
RETVAL=$?
;;
status)
$DAEMON status
RETVAL=$?
;;
*)
echo "Usage: god {start|stop|restart|status}"
exit 1
;;
esac
exit $RETVAL
Make sure to replace the directory after DAEMON by whatever your shell answers to
which boot_god
Ben and the world (/)
Then:
Step 2: Redis
I said I would’t look at it but we do need to create a conf file:
Copy paste:
# redis conf ?
daemonize no
pidfile /var/run/redis.pid
logfile stdout
port 6379
bind 127.0.0.1
timeout 300
loglevel notice
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename dump.rdb
dir /opt/redis/
appendonly no
What’s important here is that we set daemonize to no so that God can still take control
of it, and also logfile to stdout, so we can set a log file in our God configuration.
You’ll notice that I use ENV variables. That makes it easier to share variables among
the multiple files.
Copy/paste:
rails_root = ENV['RAILS_ROOT'] ?
redis_root = "/usr/bin"
w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
end
end
end
end
For Resque:
rails_env = ENV['RAILS_ENV'] ?
rails_root = ENV['RAILS_ROOT']
rake_root = ENV['RAKE_ROOT']
num_workers = rails_env == 'production' ? 2 : 1
num_workers.times do |num|
God.watch do |w|
w.name = "resque-#{num}"
w.group = 'resque'
w.interval = 30.seconds
w.env = { 'RAILS_ENV' => rails_env, 'QUEUE' => '*'
w.dir = rails_root
w.start = "#{rake_root}/rake resque:work"
w.start_grace = 10.seconds
w.log = File.join(rails_root, 'log', 'resque-worker.log'
# failsafe
on.condition(:tries) do |c|
c.times = 5
c.transition = :start
c.interval = 5.seconds
end
end
w.start_if do |start|
start.condition(:process_running) do |c|
c.interval = 5.seconds
c.running = false
end
end
end
ENV['RAILS_ENV'] = "production" ?
rails_root = ENV['RAILS_ROOT'] = "/path/to/your/app/current"
ENV['RAKE_ROOT'] = "/path/to/your/rake/bin"
load "#{rails_root}/config/god/redis.god.rb"
load "#{rails_root}/config/god/resque.god.rb"
load "#{rails_root}/config/god/resque_scheduler.god.rb"
And that should do it! Now, in the terminal, type: sudo service god start This
should start God and all its dependencies. If something seems wrong, check the log file
at /var/log/god.log and fix whatever is needed.
Bonus: Capistrano
The nice thing now is to have your workers restart every time you deploy, so that they
run the latest code. To do so, add the following in your resque.god.rb:
This will work assuming you have a task deploy:restart which “touches”
/tmp/restart.txt, which is very likely.
Last words
This is quite a complex setup and you should expect to run into a couple of issues
depending on your own configuration. Hopefully, this step by step will have made it
less painful. Let me know if that was any useful!
Before we go, I’d like to thanks all the people who I borrowed code from, even though
I’m unfortunately unable to pin point who those were.
Share
Ben and the world (/)
9 Comments Ben and the world !
1 Login
Glad it helped!
• Reply • Share ›
It is described at http://stackoverflow.com/quest...
/post/27255872468)
Theme by Pixel Union
(http://www.pixelunion.net)