Задача Upstart зависает после успешного завершения
у меня есть задача выскочки, которая запускает несколько экземпляров службы на основе запуск нескольких выскочек экземпляров автоматически и перезапуск процессов экземпляра Upstart. Он работает и запускает все экземпляры, но после их успешного запуска он просто зависает. Если Я ... --5--> out, а затем проверьте экземпляры с помощьюservice status или смотря в ps они все успешно запущены, поэтому я не знаю, что он делает, когда он болтавшийся.
вот мой скрипт:
description "all-my-workers"
start on runlevel [2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
pre-start script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
когда я делаю service start all-my-workers Я понимаю:
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers start
и потом он просто висит там и не спрашивать. Как я уже сказал, я могу!--5--> out и увидеть работающих рабочих:
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers status
all-my-workers start/running
vagrant@vagrant-service:/etc/init$ sudo service my-worker status N=1
my-worker (1) start/running, process 21938
и ps:
worker 21938 0.0 0.1 4392 612 ? Ss 21:46 0:00 /bin/sh -e /proc/self/fd/9
worker 21941 0.2 7.3 174076 27616 ? Sl 21:46 0:00 python /var/lib/my-system/script/start_worker.py
я не думаю, что проблема в my-worker.conf но на всякий случай:
description "my-worker"
stop on stopping all-my-workers
setuid worker
setgid worker
respawn
instance $N
console log
env SCRIPT_PATH="/var/lib/my-system/script/"
script
export PROVIDER=vagrant
export REGION=all
export ENVIRONMENT=cert
. /var/lib/my-system/.virtualenvs/my-system/bin/activate
python $SCRIPT_PATH/start_worker.py
END
end script
спасибо!
1 ответов
Как Это Исправить?
я собираюсь предположить, что my-worker является долгоживущим процессом, и вы хотите иметь любой простой способ вращаться и срывать несколько параллельных экземпляров my-worker.
если это так, вы, вероятно,не хочу all-my-workers быть task. Вместо этого вам нужно следующее:
description "all-my-workers"
start on runlevel [2345]
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
pre-start script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
pre-stop script
for i in `seq 1 $NUM_INSTANCES`;
do
stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
done
end script
затем вы можете запустить start all-my-workers начать все my-worker экземпляры, а затем запустите stop all-my-workers чтобы остановить их. Действенно, all-my-workers становится родительским заданием, которое управляет запуском и остановкой дочерних заданий.
почему?
вы привели два ответа SO, показывающие эту идею родительской работы, управляющей дочерними заданиями. Они показывают:
- A задание С
scriptраздела - A задание С
pre-startраздела
ваша родительская работа-это задание С pre-start строфа, и вот почему вы сталкиваетесь с этим странное поведение.
скрипт против предварительного запуска
С это спросить Ubuntu ответ ссылкой эта устаревшая документация, есть два очень важных утверждения (с выделением добавлено):
все файлы заданий должны иметь строфу exec или script. указывает, что будет выполняться задание.
дополнительный код оболочки может быть дан для запуска до или после двоичный файл или скрипт, указанный в exec или script. ожидается, что они не начнут процесс, на самом деле, они не могут. Они предназначены для подготовки окружающей среды и последующей очистки.
в общем, любые фоновые процессы, порожденные pre-start строфы игнорируются (т. е. не контролируются) выскочкой. Вместо этого ты!--42-->должны использовать exec или script чтобы породить процесс, который выскочка будет монитор.
что произойдет, если вы опустите exec/script строфа? Выскочка будет сидеть и ждать, пока процесс будет порожден. Таким образом, вы могли бы также написать while-true loop:
script
while true; do
true
done
end script
единственная разница в том, что цикл while-true является живым замком, тогда как пустая строфа приводит к мертвой блокировке.
задания и задачи
зная, выше, выскочка документация для задач в конечном итоге приводит нас к тому, что происходит on:
без задачи сайта, события, которые вызывают запуск задания, будут разблокированы сразу после запуска задания. Это означает, что задание выпустило событие starting(7), запустило его перед запуском, запустило его скрипт/exec и после запуска и выпустило событие started(7).
С задач, события, которые приводят к запуску этого задания, будут заблокированы до тех пор, пока задание полностью не перейдет обратно в stopped. Это означает, что задание выполнялось до ранее упомянутого события started(7), а также завершило свою post-stop и выпустило событие stopped (7).
(некоторые особенности о событиях и состояниях будут иметь больше смысла, если вы прочитаете документацию о запуск и остановка рабочих мест).
С точки зрения simpiler:
- С нормальной выскочкой,
exec/scriptожидается, что stanza будет блокировать бесконечно, потому что это запуск долгоживущего процесса. Таким образом, Upstart прекращает блокировку после завершенияpre-startстрофа. - С
taskнаexec/scriptожидается, что строфа будет блокироваться в течение "конечного" периода, потому что она запускает недолговечный процесс. Таким образом, Ubstart блокирует до после theexec/scriptстрофа завершится.
но что произойдет, если нет exec/script строфа? Выскочка сидит и ждет бесконечно долго, чтобы что-то быть запущен, но это никогда.
- в случае
job, это нормально, потому что выскочка не блокирует во время ожидания процесса для нереста и вызоваstopпо-видимому, достаточно, чтобы он перестал ждать. - в случае
task, однако, выскочка будет просто сидеть и висеть вечно - или пока вы не прервете его. Однако, поскольку он все еще не нашел порожденный процесс, он все еще технически работает. Вот почему вы можете запросить статус после прерывания и увидетьall-my-workers start/running.
ради интереса
если по какой-то причине вы действительно хотите сделать свою родительскую работу задачей, вам действительно понадобится два задачи: один, чтобы начать my-worker экземпляров и один, чтобы остановить их. Вам также необходимо удалить stop on stopping all-my-workers строфа из my-worker.
start-all-my-workers:
description "starts all-my-workers"
start on runlevel [2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
стоп-все-мои-работники:
description "stops all-my-workers"
start on runlevel [!2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
script
for i in `seq 1 $NUM_INSTANCES`;
do
stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
done
end script