Using God to Monitor Unicorn - Start Exited with Non-Zero Code = 1

Using God to monitor Unicorn - Start exited with non-zero code = 1

I haven't used unicorn as an app server, but I've used god for monitoring before.

If I remember rightly when you start god and give your config file, it automatically starts whatever you've told it to watch. Unicorn is probably already running, which is why it's throwing the error.

Check this by running god status once you've started god. If that's not the case you can check on the command line what the comand's exit status is:

/usr/local/bin/unicorn_rails -c /home/my-linux-user/my-rails-app/config/unicorn.rb -E production -D;
echo $?;

that echo will print the exit status of the last command. If it's zero, the last command reported no errors. Try starting unicorn twice in a row, I expect the second time it'll return 1, because it's already running.

EDIT:

including the actual solution from comments, as this seems to be a popular response:

You can set an explicit user and group if your process requires to be run as a specific user.

God.watch do |w|
w.uid = 'root'
w.gid = 'root'

# remainder of config
end

god doesn't stop unicorn

Now we are using foreman and puma right now...this is our initializer:


web: bundle exec puma -q -d -e production -b 'unix:///home/api/shared/web.socket' -S /home/api/shared/web.state --control 'unix:///home/api/shared/web.ctl'

and deploying with capistrano, so that we can stop and restart the server like this

config/deploy.rb

# Puma commands
_cset(:puma_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec puma" }
_cset(:pumactl_cmd) { "#{fetch(:bundle_cmd, 'bundle')} exec pumactl" }
_cset(:puma_state) { "#{shared_path}/puma.state" }
_cset(:puma_role) { :app }

# Puma
namespace :puma do

desc 'Start puma'
task :start do
run "cd #{current_path} ; bundle exec foreman start web"
end

desc 'Stop puma'
task :stop, :roles => lambda { fetch(:puma_role) }, :on_no_matching_servers => :continue do
run "cd #{current_path} && #{fetch(:pumactl_cmd)} -S #{fetch(:puma_state)} stop"
end

desc 'Restart puma'
task :restart, :roles => lambda { fetch(:puma_role) }, :on_no_matching_servers => :continue do
run "cd #{current_path} && #{fetch(:pumactl_cmd)} -S #{fetch(:puma_state)} restart"
end
end

Using god only to kill

Answer to your question lies in question itself. you can kill ruby processes using god gem which is ruby process process monitor framework by github guys.

basically, here is how it works:

  1. configure god to monitor process it can be anything from apache,passenger,mongrel or just simple file doing a long-running task.
  2. Set conditionals in god's configuration file based upon which god will execute some predefined code.

here is a simple example(taken from docs). consider this as file long running process that runs undefiantly which we want to monitor for memory usage, lets call it simple.rb

loop do
puts 'Hello'
sleep 1
end

now, we install the god gem & configure it to as run as superuser so it can kill/spawn processes and next create a configuration file. example(also taken from docs):

God.watch do |w|
w.name = "simple"
w.start = "ruby /full/path/to/simple.rb"
w.keepalive(:memory_max => 500.megabytes)
end

Here, as you may have got the idea if the process memory usage goes above 500 megabytes, god will restart it. here are few resources that might help, if you are getting started with process management using god gem:

  • Example gist - Passenger worker monitor to kill workers which use too much RAM(Don't use god, but spawns a new passenger worker instead)
  • Project Homepage
  • Github Page
  • An indepth tutorial using god with rails & passenger

Now, please remember ALL configuration for god is actually legal ruby code so you can get creative & do all sorts of things.

lastly, if you are frequently finding yourself running long running process, I advice you to try JRuby which is works much better with long running processes due to JVM & LOT faster than MRI

how to make foreman start god

You should not be running god with foreman. foreman is used to specify all the background (and web) processes in your application, and god is a process monitoring framework for those processes.

Typically, you should:

  1. Specify all your processes directly in your Procfile (instead of services.god), and use foreman start to run them in development.
  2. Use god to monitor the processes in production. I use my foreman_god gem to load the Procfile directly with god. Alternatively, you can export a god config file.

That said, if you really want to run god from foreman: god runs as a daemon by default, and daemons don't work with foreman (see this wiki page). It should work if you pass the -D (Don't daemonize) option to god:

god: god -D -c services.god


Related Topics



Leave a reply



Submit