Задача 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