2010-11-05 37 views
4

J'ai plusieurs applications de rails déployées par passager nginx. Je veux que ces applications soient surveillées en utilisant monit. Comment puis-je surveiller ces applications en utilisant monit? Dois-je surveiller nginx aussi?Comment surveiller le passager nginx avec le monit

+0

passager 2 ou passager 3. Si le passager 3 est autonome ou non? – shingara

+0

J'utilise passager 3, mais la copie copiée du passager 2. Fondamentalement, c'est le passager 2. – Chamnap

+0

Je ne suis pas sûr mais, monit peut surveiller un processus avec donner PID afin que vous puissiez créer des fichiers PID pour chaque processus que vous souhaitez surveiller. En ce qui concerne nginx, vous devez surveiller nginx comme étant le processus principal qui gère votre requête Web et la délègue à une instance de passager. –

Répondre

3

Voici comment j'ai résolu cela. Tout d'abord, j'ai ajouté à application.rb:


# Monit support 
if defined?(PhusionPassenger) 
    require 'pidfile_manager' 
    PhusionPassenger.on_event(:starting_worker_process) do |forked| 
    if forked 
     # We're in smart spawning mode. 
     PidfileManager.write_pid_file 
    else 
     # We're in conservative spawning mode. We don't need to do anything. 
    end 
    end 

    PhusionPassenger.on_event(:stopping_worker_process) do 
    PidfileManager.remove_pid_file 
    end 
end 

et je mis à exécution les PidfileManager:


module PidfileManager 
    extend self 

    BASENAME = '/var/tmp/rack.*.pid' 

    def write_pid_file 
    pid = Process.pid 
    count = 1 
    pidfile = nil 
    go_over_pid_files do |file, saved_pid| 
     file_id = file[/(\d+)/,1].to_i 
     # Increase counter only if we met the same file id 
     count += 1 if file_id == count 
     # We're already there 
     return if saved_pid == pid 
     # Check if the process is alive 
     res = begin 
     Process.kill(0, saved_pid) 
     rescue Errno::ESRCH 
     nil 
     end 
     # It's dead, reuse 
     unless res 
     pidfile = file 
     break 
     end 
    end 
    pidfile ||= BASENAME.sub('*', count.to_s) 
    File.open(pidfile, 'w') {|f| f.write(pid.to_s)} 
    end 

    def remove_pid_file 
    pid = Process.pid 
    go_over_pid_files do |file, saved_pid| 
     if pid == saved_pid 
     File.unlink(file) 
     break 
     end 
    end 
    end 

    private 
    def go_over_pid_files 
    Dir[BASENAME].each do |file| 
     saved_pid = File.read(file).to_i 
     yield file, saved_pid 
    end 
    end 

end 

Et vous venez de dire Monit pour surveiller chaque cas en utilisant /var/tmp/rack.X. pid en tant que fichier pid.

+1

J'ai fait un plugin - https://github.com/romanbsd/passenger_monit – Roman

0

Si vous voulez les faire fonctionner et les faire redémarrer en cas d'erreur, mieux vaut regarder supervisord. Plutôt que d'interroger pour voir si un processus est en cours d'exécution, supervord exécute le processus lui-même. Les démons qu'il exécute doivent exécuter le premier plan pour qu'il fonctionne, mais il est très efficace et apportera des services beaucoup plus rapidement que le monit (le sondage interroge généralement chaque minute, tandis que supervord verrait le processus se terminer et le redémarrer instantanément).

Nous utilisons supervord en production qui exécute tous nos démons (nginx, beanstalkd, memcached, divers services python, etc.), puis utilisons monit pour surveiller supervord comme une sauvegarde supplémentaire.

+0

OP a demandé spécifiquement au sujet des applications Rails fonctionnant sous Nginx Passenger, qui n'est pas abordée dans cette réponse. – Amir

2

Je ne sais pas si son trop tard pour poster cela, mais voici comment j'utilise Monit (5,14) pour arrêter les rails de passagers apps consomment trop de mémoire:

Monit:

check program ourapp_live with path  "/usr/local/bin/check_passenger_mem_usage ourapp 500" as "ourappuser" 
if status != 0 then alert 
if status != 0 then restart 
start program = "/bin/touch /var/www/vhosts/ourapp/railsapp/current/tmp/restart.txt" 
stop program = "/bin/true" 

La coquille appels Monit script (de check_passenger_mem_usage):

#!/bin/bash 
# 
# 
USER=$1 
TRIGGER=$2 

if [ -z $USER ] || [ -z $TRIGGER ] 
then 
    echo "missing args" 
    echo "usage:" 
    echo "   check_passenger_mem_usage username alert_threshold" 
    echo 
    echo "(alert_threshold is in mb)" 
    echo 
    exit 1 
fi 

MAX=`/usr/local/rvm/gems/ruby-1.8.7-p357/wrappers/passenger-memory-stats | grep $USER | awk '{print $2}' | sort -n | tail -1|cut -d. -f1` 

if [ "$MAX" -gt $TRIGGER ] 
then 
    echo 
    echo "${USER}: We got a runaway! Gobbling ${MAX} mb" 
    echo 
    exit 1 
else 
    echo 
    echo "Max is ${MAX}" 
    exit 0 
fi 

Probablement pas la meilleure solution car il redémarre l'ensemble de rails application, mais au moins il empêche les rails consommant de grandes quantités de Memor y devrait l'application aller un peu de mémoire intensive de temps en temps.