Deutsch
Germany.ruФорумы → Архив Досок→ Linux & Co

supervisor [too many start retries too quickly]

376  
  Posmotrim знакомое лицо17.04.14 12:55
Posmotrim
17.04.14 12:55 
Последний раз изменено 17.04.14 13:04 (Posmotrim)
Всем привет,
есть php скрипт, который выгребает сообщения из очереди rabbitmq и выполняет определённые задания. Тоесть некий сервер задач. Так как в пыхе подтекает память, то скрипт, после определённого кол-ва выполненных задач раз завершается, ну а supervisor следит за ним и поднимает заново. При определённых условиях накапливается большое кол-во мелких задач, выполнение которых длится милисекунды.
В логе супервизора имею:
2014-04-15 17:30:29,516 INFO spawned: 'mq' with pid 11373
2014-04-15 17:30:29,569 INFO exited: mq (exit status 0; not expected)
2014-04-15 17:30:30,576 INFO spawned: 'mq' with pid 11375
2014-04-15 17:30:30,649 INFO exited: mq (exit status 0; not expected)
2014-04-15 17:30:32,658 INFO spawned: 'mq' with pid 11377
2014-04-15 17:30:32,733 INFO exited: mq (exit status 0; not expected)
2014-04-15 17:30:35,744 INFO spawned: 'mq' with pid 11379
2014-04-15 17:30:35,818 INFO exited: mq (exit status 0; not expected)
2014-04-15 17:30:36,820 INFO gave up: mq entered FATAL state, too many start retries too quickly
после того, как перешли в статус FATAL - супервизор перестаёт запускать данную задачу. Пока удалось выкрутиться следующим образом: при старте скрипта замеряю время, и при выходе из него, если не прошла 1 секунда, просто жду.
Условно:

public function actionUserService()
{
$started = time();

//...
while (true)
{
if ($envelope = $queue->get())
{
//тут обработка задачи
//....
//пусть supervisor нас перезапустит
if($attempts++ > self::MAX_ATTEMPTS_NUMBER)
{
//вот такой костыль, но ничего лучшего не могу придумать :((
if(time() - $started < 2)
{
sleep(1);
}
break;
}
}
else
{
sleep(1); //тут не критично ждать, так как задач нет
}
}
}


Костыль рабочий, но, при большом количестве мелких задач появляется пауза в одну секунду между обработками пакетов задач. Фактически мы может получится , что мы ждём больше, чем работаем.
Если можно, без рассуждений, на тему уместет ли тут пхп.
Спасибо.

#1 
  anatoli888 завсегдатай17.04.14 20:50
NEW 17.04.14 20:50 
в ответ Posmotrim 17.04.14 12:55
rabbitmq не знаю. знаю redis
http://kamisama.me/2011/11/07/php-rescue-with-phpredis
#2 
  Posmotrim знакомое лицо18.04.14 09:26
Posmotrim
NEW 18.04.14 09:26 
в ответ anatoli888 17.04.14 20:50, Последний раз изменено 18.04.14 12:53 (Posmotrim)
Скорее всего без разницы, на чём очередь организованна. В php подтекает память(ну не для долгоживущих он процессов) и необходимо с этим как-то бороться. Самое простое решение - перезапускать процесс. Так как supervisor всё равно используется, логично ему поручить перезапускать php процесс. Проблема в том, что supervisor-у не нравятся частые перезапуски и время работы управляемого процесса(см. логи выше). Или я просто не правильно его настроил.
#3 
  anatoli888 завсегдатай18.04.14 16:54
NEW 18.04.14 16:54 
в ответ Posmotrim 18.04.14 09:26
что ты подразумеваешь под "подтекает память"?
#4 
  Posmotrim знакомое лицо18.04.14 17:03
Posmotrim
NEW 18.04.14 17:03 
в ответ anatoli888 18.04.14 16:54
имею ввиду утечки памяти. некоторые можно устранить(свой код), есть те, которые нет возможности устранить: расширения, зоопарк используемых библиотек, некоторые системные функции.
в интернете полно материалов на эту тем. вот например: http://rmcreative.ru/blog/post/utechki-pamjati-v-php
#5 
Где карта,Билли? постоялец04.06.14 10:12
Где карта,Билли?
NEW 04.06.14 10:12 
в ответ Posmotrim 17.04.14 12:55
что мешает убить воркера и стартануть нового, когда у него MAX_ATTEMPTS_NUMBER больше, чем надо? Никаких слипов не надо и ждать тоже.
ну и поновее пхп взять. тоже поможет.
#6 
  Posmotrim знакомое лицо04.06.14 16:17
Posmotrim
NEW 04.06.14 16:17 
в ответ Где карта,Билли? 04.06.14 10:12
В ответ на:
что мешает убить воркера и стартануть нового, когда у него MAX_ATTEMPTS_NUMBER больше, чем надо?

так и сделано. при выходе из actionUserService завершается процесс php. а supervisor перезапускает.
В ответ на:

Никаких слипов не надо и ждать тоже.

попробуй сам:
[program:xx]
command=php /путь/к/файлику.php
numprocs=1
autorestart=true
autostart=true
в файле просто сделай вывод на печать.
В ответ на:
ну и поновее пхп взять.

ssm@debian:/var/run$ php -v
PHP 5.4.28-1~dotdeb.1 (cli) (built: May 7 2014 22:16:44)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans
#7