J'ai initialement posé cette question sur StackOverflow. Puis réalisé que c'est probablement un meilleur endroit.
J'ai la configuration bluepill pour surveiller mes processus delay_job. (Ruby sur Rails application)
Utiliser Ubuntu 12.10.
Je lance et surveille le service bluepill lui-même à l'aide de upstart
d'Ubuntu. Ma configuration initiale est ci-dessous (/etc/init/bluepill.conf
).
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
expect daemon
exec Sudo /home/deploy/.rvm/wrappers/<app_name>/bluepill load /home/deploy/websites/<app_name>/current/config/server/staging/delayed_job.bluepill
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
J'ai également essayé avec expect fork
au lieu de expect daemon
. J'ai également essayé de supprimer complètement la ligne expect...
.
Lorsque la machine démarre, bluepill démarre bien.
$ ps aux | grep blue
root 1154 0.6 0.8 206416 17372 ? Sl 21:19 0:00 bluepilld: <app_name>
Le PID du processus bluepill est ici 1154. Mais upstart
semble suivre le mauvais PID. Il suit un PID qui n'existe pas.
$ initctl status bluepill
bluepill start/running, process 990
Je pense que cela suit le PID du processus Sudo
qui a démarré le processus bluepill.
Ceci empêche le processus de bluepill d'être réapparu si je tue de force le bluepill en utilisant kill -9
.
De plus, je pense qu'en raison du mauvais PID suivi, le redémarrage/arrêt se bloque et je dois réinitialiser la machine à chaque fois.
Quel pourrait être le problème ici?
UPDATE:
Le problème persiste aujourd'hui (3 mai 2015) sur Ubuntu 14.04.2.
Le problème n'est pas dû à l'utilisation de Sudo. Je n'utilise plus Sudo. Ma configuration upstart mise à jour est la suivante:
description "Start up the bluepill service"
start on runlevel [2]
stop on runlevel [016]
# Restart the process if it dies with a signal
# or exit code not given by the 'normal exit' stanza.
respawn
# Give up if restart occurs 10 times in 90 seconds.
respawn limit 10 90
expect daemon
script
shared_path=/home/deploy/websites/some_app/shared
bluepill load $shared_path/config/delayed_job.bluepill
end script
Lorsque la machine démarre, le programme se charge correctement. Mais Upstart suit toujours le mauvais PID, comme décrit ci-dessus.
La solution de contournement mentionnée dans les commentaires peut résoudre le problème suspendu. Je n'ai pas essayé, cependant.
Assez tard, mais j'espère que cela pourra aider d'autres utilisateurs.
Il y a un bogue documenté dans upstart qui peut amener initctl à suivre le PID incorrect si vous spécifiez la strophe fork
incorrecte dans une configuration upstart: https://bugs.launchpad.net/upstart/+bug/406397 =
Ce qui se passe, c’est que upstart vérifie la strophe fork
et détermine le nombre de processus en chaîne qu’il doit vérifier avant de choisir le "vrai" PID du programme contrôlé. Si vous spécifiez expect fork
ou expect daemon
mais que votre programme ne se divise pas en nombre suffisant, start
se bloque. Si, en revanche, votre processus recourt trop souvent, initctl
suivra le mauvais PID. Théoriquement, il devrait être documenté dans ceci section du livre de recettes upstart , mais comme vous pouvez le voir dans cette situation, un PID est associé au processus tué, alors qu'il ne devrait pas en être.
Les implications de ceci sont expliquées dans les commentaires de bugtracker, mais je vais résumer ici: outre initctl
name__, ne pas pouvoir arrêter le processus du démon et être bloqué dans un état non documenté/illégal <service> start/killed, process <pid>
, si le processus appartenant à ce PID s'arrête (et généralement le PID est libéré pour être réutilisé par le système.
Si vous émettez initctl stop <service>
ou service <service> stop
, initctl
supprimera ce PID lors de sa prochaine apparition. Cela signifie que quelque part sur la route si vous ne redémarrez pas après avoir commis cette erreur, le prochain processus d'utilisation de ce PID sera immédiatement tué par initctl
même s'il ne s'agira pas du démon. Cela pourrait être quelque chose d'aussi simple que cat
ou d'aussi complexe que ffmpeg
name__, et vous auriez du mal à comprendre pourquoi votre progiciel est tombé en panne au milieu d'une opération de routine.
Le problème est donc que vous avez spécifié la mauvaise option expect
pour le nombre de fourches réellement générées par votre processus démon. Ils disent qu'il y a une réécriture récente qui aborde ce problème, mais qu'à partir de la dernière version 1.8 (dernière Ubuntu 13.04/Janvier 2014), le problème est toujours présent.
Puisque vous avez utilisé expect daemon
et que vous avez eu ce problème, je vous recommande d'essayer expect fork
.
Edit: Voici un script compatible Ubuntu BASH ( original de Wade Fitzpatrick modifié pour utiliser Ubuntu sleep
name__) qui génère des processus jusqu'à épuisement de l'espace d'adressage d'ID de processus disponible. Il démarre à 0 et fonctionne à nouveau. son chemin jusqu'au PID "bloqué". Un processus est ensuite généré lorsque le PID initctl
est suspendu et initctl
le tue et le réinitialise.
#!/bin/bash
# usage: sh /tmp/upstart_fix.sh <pid>
sleep 0.001 &
firstPID=$!
#first lets exhaust the space
while (( $! >= $firstPID ))
do
sleep 0.001 &
done
# [ will use testPID itself, we want to use the next pid
declare -i testPID
testPID=$(($1 - 1))
while (( $! < $testPID ))
do
sleep 0.001 &
done
# fork a background process then die so init reaps its pid
sleep 3 &
echo "Init will reap PID=$!"
kill -9 $$
# EOF
Pour l'exemple fourni:
$ initctl status bluepill
bluepill start/running, process 990
une solution rapide pour moi est:
# If upstart gets stuck for some job in stop/killed state
export PID=990
cd /usr/local/bin
wget https://raw.github.com/ion1/workaround-upstart-snafu/master/workaround-upstart-snafu
chmod +x workaround-upstart-snafu
./workaround-upstart-snafu $PID
source: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=582745#37
J'espère que cela vous sera utile. Ce qui se passe est expliqué dans les autres réponses.
Sauf si vous exécutez un travail de niveau utilisateur Upstart ou à l'aide de la strophe setuid -, votre travail s'exécute en tant que root.
Comme Upstart fonctionne déjà en tant que root, pourquoi avez-vous besoin d'utiliser Sudo dans votre strophe exec
name__?
L'utilisation de Sudo
ou su
dans la strophe exec
a causé les mêmes problèmes que ceux décrits ci-dessous.
En général, je vais faire l'expérience du point 1 OR à la fois 1 ET 2:
Bien entendu, vous devez en outre que la strophe expect
reflète le nombre correct de fourches.
YMMV, mais pour moi:
exec
avec le nombre correct de fourches spécifié, vous obtenez généralement la situation 1 ci-dessus.exec
name__) entraîne la situation 1 ET 2 ci-dessus.