Стартиране и спиране на celery процеси в upstart със скрипт за обвивка на python

Така че имаме приложение, което има работещи с целина. Стартираме тези работници с помощта на файл за стартиране /etc/init/fact-celery.conf, който изглежда по следния начин:

description "FaCT Celery Worker."
start on runlevel [2345]
stop on runlevel [06]

respawn
respawn limit 10 5

setuid fact
setgid fact

script
  [ -r /etc/default/fact ] && . /etc/default/fact

  if [ "$START_CELERY" != "yes" ]; then
    echo "Service disabled in '/etc/default/fact'. Not starting."
    exit 1
  fi

  ARGUMENTS=""

  if [ "$BEAT_SERVICE" = "yes" ]; then
    ARGUMENTS="--beat"
  fi

  /usr/bin/fact celery worker --loglevel=INFO --events --schedule=/var/lib/fact/celerybeat-schedule --queues=$CELERY_QUEUES $ARGUMENTS
end script

Той извиква скрипт за обвивка на Python, който изглежда по следния начин:

#!/bin/bash

WHOAMI=$(whoami)
PYTHONPATH=/usr/share/fact
PYTHON_BIN=/opt/fact-virtual-environment/bin/python
DJANGO_SETTINGS_MODULE=fact.settings.staging

if [ ${WHOAMI} != "fact" ];
then
  sudo -u fact $0 $*;
else
  # Python needs access to the CWD, but we need to deal with apparmor restrictions
  pushd $PYTHONPATH &> /dev/null
  PYTHONPATH=${PYTHONPATH} DJANGO_SETTINGS_MODULE=${DJANGO_SETTINGS_MODULE}  ${PYTHON_BIN} -m fact.managecommand $*;
  popd &> /dev/null
fi

Проблемът с тази настройка е, че когато спрем услугата, ни остават pact-celery работници, които не умират. По някаква причина upstart не може да проследи раздвоените процеси. Четох в някои подобни публикации, че новостартът не може да проследи повече от два форка.

Опитах да използвам expect fork, но след това upstart просто увисва, когато се опитам да стартирам или спра услугата.

Други публикации, които открих по този въпрос, казват директно извикване на процеса на python, вместо използване на скрипта за обвивка, но ние вече сме изградили профили на apparmor около тези скриптове и има други неща в нашия работен процес, които са доста зависими от тях.

Има ли някакъв начин, с текущите скриптове за обвивка, да се справим с убиването на всички работещи с целина при спиране на услугата?


person djsumdog    schedule 12.03.2015    source източник


Отговори (1)


Има известна дискусия по този въпрос в Ръководство за работници, но по същество обичайният процес е да се изпрати сигнал TERM към работника, което ще го накара да изчака всички изпълнявани в момента задачи да приключат, преди да излезе чист.

Като алтернатива можете да изпратите сигнала KILL, ако искате той да спре незабавно с потенциална загуба на данни, но тогава, както казахте, целината не може да прихване сигнала и да изчисти децата в този случай. Единственото споменато средство е ръчно почистване на децата по следния начин:

$ ps auxww | grep 'celery worker' | awk '{print $2}' | xargs kill -9

person Chris Ward    schedule 12.03.2015