Skip to content

Instantly share code, notes, and snippets.

@sawanoboly
Created October 27, 2011 12:16
Show Gist options
  • Save sawanoboly/1319398 to your computer and use it in GitHub Desktop.
Save sawanoboly/1319398 to your computer and use it in GitHub Desktop.
RackServer thin with god (cluster multi processes)
# http://god.rubyforge.org/
# http://unicorn.bogomips.org/SIGNALS.html
# http://railscasts.com/episodes/130-monitoring-with-god
rails_env = ENV['RAILS_ENV'] || 'production'
rails_appname = ENV['RAILS_APPNAME'] || 'appname'
rails_root = ENV['RAILS_ROOT'] || "/opt/deploy/#{rails_appname}/current"
num_workers = rails_env == 'production' ? 8 : 1
thin_rootport = 3000
def generic_monitoring(w, options = {})
# generic_monitoring option list
# option list
# [:start_grace], [:stop_grace], [:restart_grace]
# [:cpu_interval], [:cpu_limit], [:memory_interval], [:memory_limit], [:contact]
w.start_grace = options[:start_grace]
w.stop_grace = options[:stop_grace]
w.restart_grace = options[:restart_grace]
# determine the state on startup
w.transition(:init, { true => :up, false => :start }) do |on|
on.condition(:process_running) do |c|
c.running = true
c.notify = options[:contact]
end
end
# determine when process has finished starting
w.transition([:start, :restart], :up) do |on|
on.condition(:process_running) do |c|
c.running = true
c.notify = options[:contact]
end
# failsafe
on.condition(:tries) do |c|
c.times = 5
c.transition = :start
c.notify = options[:contact]
end
end
# start if process is not running
w.transition(:up, :start) do |on|
on.condition(:process_exits) do |c|
c.notify = options[:contact]
end
end
# restart if memory or cpu is too high
w.transition(:up, :restart) do |on|
on.condition(:memory_usage) do |c|
c.interval = options[:memory_interval]
c.above = options[:memory_limit]
c.times = [3, 5]
c.notify = options[:contact]
end
on.condition(:cpu_usage) do |c|
c.interval = options[:cpu_interval]
c.above = options[:cpu_limit]
c.times = [3, 5]
c.notify = options[:contact]
end
end
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
c.to_state = [:start, :restart]
c.times = 5
c.within = 5.minute
c.transition = :unmonitored
c.retry_in = 10.minutes
c.retry_times = 5
c.retry_within = 2.hours
c.notify = options[:contact]
end
end
end
num_workers.times do |num|
God.watch do |w|
port = thin_rootport + num
w.name = "#{rails_appname}_thin_#{port}"
w.group = "#{rails_appname}"
w.interval = 5.seconds
w.dir = rails_root
w.pid_file = File.join(rails_root, "/tmp/pids/thin.#{port}.pid")
w.start = "bundle exec thin -R ./thin_#{rails_appname}.ru -e #{rails_env} -s #{num_workers} -p #{thin_rootport} -o #{num} -d start"
# QUIT gracefully shuts down workers
w.stop = "bundle exec thin -s #{num_workers} -p #{thin_rootport} -o #{num} stop"
# w.stop_signal = 'QUIT'
# or god signal USR2 #{app}
w.restart = "bundle exec thin -R ./thin_#{rails_appname}.ru -e #{rails_env} -s #{num_workers} -p #{thin_rootport} -o #{num} restart"
w.uid = 'root'
w.gid = 'root'
w.behavior(:clean_pid_file)
# generic_monitoring option list
# [:start_grace], [:stop_grace], [:restart_grace]
# [:cpu_interval], [:cpu_limit], [:memory_interval], [:memory_limit], [:contact]
generic_monitoring(w,
:start_grace => 10.seconds,
:stop_grace => 10.seconds,
:restart_grace => 10.seconds,
:cpu_interval => 60.seconds,
:cpu_limit => 30.percent,
:memory_interval => 60.seconds,
:memory_limit => 200.megabytes,
:contact => 'mailto',
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment