Jump to content
Калькуляторы

Странности с планировщиком (Debian Linux, cron)

Есть у меня несколько сервисных скриптов.

Например такой:

#!/usr/bin/php -q
<?php

if (php_sapi_name() != 'cli') die("Jobs allowed from shell (cli) only\n");

include("../lib/header.php");

$bm = Billing::getInstance();
$agents = $bm->select('PAYMENT_AGENT', 'ID', null, array('ID'=>'PAYMENT_AGENT_ID', 'CLASS', 'CODE', 'NAME', 'TRADENAME', 'TZ'));
$checks = $bm->select('PAYMENT_AGENT_TRANSPORT', null, array('TRANSPORT'=>'email'));

$email = TransportFactory::create('email');
$email->onRecv('processing');
$email->recv();
unset($email);

function processing($request)
{
   echo "Get request, from <" . $request->from . ">\n";
   ...
}

 

Скрипт проверяет электронную почту, обрабатывает письма и после шлет мне на email отчет по обработке. В процессе обработки выводит в консоль различную информацию.

Если запускать скрипт интерактивно, то он всегда отрабатывает нормально, хоть из под root, хоть из под пользователя.

 

Скрипт запускается по расписанию.

В планировщик добавлена такая строчка:

5 * * * * user1 cd /jobs/job1 && ./job1.sh  >> output.log 2>&1

И к нему скрипт-обертка /jobs/job1/job1.sh для запуска:

#!/bin/sh

echo "Call job1, `date`..."
cd /tools/php
/usr/bin/php -q job1.php

 

Работу скрипта я вижу по приходящим на электронную почту отчетам.

Какое-то время скрипт нормально запускается из планировщика, результаты выполнения выводятся в файл output.log.

Но потом в какой-то момент скрипт перестает работать.

Если просмотреть файл output.log, то в нем последней строкой будет что-то такое:

Call job1, Thu Apr 16 21:12:52 MSK 2015
Get request, fro

 

Что это может быть?

Почему вывод в файл может обрываться на середине слова?

Если «поломался» PHP-скрипт, то почему в файле output.log нет вывода из скрипта-обертки, который выводит «Call job1»?

Если файл output.log просто удалить, то работа скрипта возобновляется. На какое-то время, а затем снова проблема повторяется.

Никто с таким не сталкивался?

Share this post


Link to post
Share on other sites

может logrotate настроен на ваш output.log?

это веду к тому, что может что-то с правами

Edited by BETEPAH

Share this post


Link to post
Share on other sites

Бывают обрывки вывода при падении в корку. Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них. Проверьте обработку текста.

Edited by vop

Share this post


Link to post
Share on other sites

Как вариант, скрипт натыкается на письмо с какими-нибдуь "неправильными" символами внутри, и подрывается на них.

Возможно, в электронной почте куча подобных ситуаций.

Но почему тогда не срабатывают следующие вызовы планировщика (через час)?

 

это веду к тому, что может что-то с правами

Права 644, владелец user1.

Для пробы я делал права 666, не помогало.

Share this post


Link to post
Share on other sites
Возможно, в электронной почте куча подобных ситуаций.

 

Там ожет быть еще путаница с кодесетами... Но то уже такое.

 

Но почему тогда не срабатывают следующие вызовы планировщика (через час)?

 

Он насовсем перестает работать? Но вот это же должно хотя бы выводиться:

 

echo "Call job1, `date`..."

 

Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко? Надо бы его глянуть, может что там ломано.

 

И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)? Может там с конкурентным доступом что-нибудь не так?

Share this post


Link to post
Share on other sites

Он насовсем перестает работать? Но вот это же должно хотя бы выводиться:

Вот именно.

Как будто крон выключился.

Или как будто не хватает прав на добавление текста в output.log.

Но крон работает (другие задания выполняются) и права на файле 644 с владельцем user1.

 

Если выводится, и при каждом запуске затыкается на выводе строки "fro", может, как раз, и первым в обработке и стоит "кривое" письмишко?

Если скрипт запустить вручную, он это письмо обрабатывает нормально.

 

И еще вопросик - при обработке сообщений там все правильно устанавливается (блокировки и т.д.)?

«Там» это где? На сервере электронной почты?

Share this post


Link to post
Share on other sites

Может скрипт слишком долго работает и крон его по таймауту прибивает? А из за такого прибивания буфер stdout нормально не сбрасывается в файл?

Попробуйте запускать скрипт через setsid и на конце &

Share this post


Link to post
Share on other sites

Может скрипт слишком долго работает и крон его по таймауту прибивает?

Может и так. У IMAP таймауты большие.

Правда это по идее не должно мешать повторному вызову.

 

Попробуйте запускать скрипт через setsid и на конце &

Через setsid запускать скрипт-обертку или PHP-скрипт?

Share this post


Link to post
Share on other sites

Любопытная статистика накопилась.

Скорее всего дело вообще не в правах доступа.

 

Итак, в планировщик добавлена примерно такая строчка:

cd /jobs/job1 && ./job1.sh  >> output.log 2>&1

job1.sh это файл-обертка, в котором первой строчкой стоит команда date (выводит текущую дату/время), а второй запуск php или perl скрипта.

Какое-то время это задание успешно запускается, вывод дописывается в файл output.log.

Затем задание перестает работать, в output.log вывод обрывается на середине слова.

 

Если просто удалить файл output.log, то при следующем срабатывании планировщика в каталоге появляется пустой output.log.

Странность тут в том, что раз файл output.log создается, значит строка планировщика сработала.

А вдвойне странно то, что этот файл пустой — если уж sh-скрипт запустился, то хотя бы дату и время он должен был вывести.

Третья странность — какие-бы права доступа на этот файл я не задавал, хоть 666, скрипт не работает и вывод в output.log не добавляется.

Но если я интерактивно выполню такую команду (под любым пользователем, хоть user1, хоть root):

cd /jobs/job1 && ./job1.sh  >> output.log

(то есть после выполнения этой команды будет непустой файл output.log)

и затем для файла output.log пропишу права 666, то скрипт снова начинает работать какое-то время.

Такое впечатление, как будто при запуске строки из планировщика файл output.log создается какой-то неправильный и в него невозможно дописать данные.

Share this post


Link to post
Share on other sites

Если обрывается на полуслове, или вообще ничего не выводит, то, возможно, вылетает по сегментейшн фаулт. Сам крон по емейлу что пишет?

Share this post


Link to post
Share on other sites

У меня когда-то была примерно такая же проблема: при интерактивном запуске отрабатывало, при запуске из крона - результат был непредсказуемый.

"Вылечилось" примерно такой крон-строкой:

 

02 05 * * * . /homeuser/.profile;/usr/bin/script

Edited by altnetwork.ru

Share this post


Link to post
Share on other sites

Сам крон по емейлу что пишет?

Ничего. core-файлов тоже нигде не видно.

К тому же я ведь не рестартую crond. Я планировщик вообще не трогаю, но если я создаю файл output.log с содержимым, то задания начинают отрабатывать нормально.

 

"Вылечилось" примерно такой крон-строкой

А что это дает?

Мой user1 - это служебный пользователь, у которого нет home.

Просмотрел свой home - там только переменные окружения выставляются. А в рутовом - и того нет.

Share this post


Link to post
Share on other sites

Уверен, что с буферизацией самого php разобрался?

ob_flush() и flush() в конце программы попробуй

Share this post


Link to post
Share on other sites

Я где-то читал, что когда PHP запускается интерактивно (php_sapi_name()=='cli'), то он сам отключает буферизацию.

Но даже если это не так, я почти на 100% уверен, что причина не в буферизации.

Во-первых, такое же поведение наблюдается и для perl-скриптов, в которых я отключаю буферизацию ($|=1).

Во-вторых, это не объясняет, почему в файле output.log нет вывода команды date, которая указана в sh-файле перед запуском собственно скрипта.

Share this post


Link to post
Share on other sites

Я бы для начала посмотрел логи php.

 

И уберите обертку, она не нужна.

Вывод в файл также не самый удачный подход для логирования.

Share this post


Link to post
Share on other sites

Я бы для начала посмотрел логи php.

А такое бывает?

Где их можно посмотреть?

Share this post


Link to post
Share on other sites

Я бы для начала посмотрел логи php.

А такое бывает?

Где их можно посмотреть?

 

сомнительно что бывает, а вот обертку можно и убрать и вызывать из под пхп date()

Share this post


Link to post
Share on other sites

echo "Get request, from <" . $request->from . ">\n";

Возможно, проблема в неэкранированном знаке <, в процессе выполнения скрипта-обертки получается вызов

print abc < def > >> output.log

 

переделайте обертку на

#!/bin/sh
LOG="/jobs/job1/output.log"
echo "Call job1, `date`..." >> $LOG
cd /tools/php
/usr/bin/php -q job1.php >> $LOG

Share this post


Link to post
Share on other sites

А такое бывает?

Где их можно посмотреть?

Включите их в php.ini

error_log = /path/filename

Share this post


Link to post
Share on other sites

есть подозрение, что крон запускает новое задание (скажем, в 10 минут), когда не закончилось выполнение предыдущего (запущенного, скажем, в 05 минут)

php-скрипт реентерабелен?

Share this post


Link to post
Share on other sites

Планировщик запускается раз в час, скрипт выполняется в среднем менее минуты (иногда бывает дольше из-за больших таймаутов IMAP).

Параллельный запуск двух экземпляров по идее мешать не должен, там нет причин для взаимных блокировок.

 

Обертку переделаю, посмотрю как это повлияет.

Но сейчас уже третьи сутки задания выполняются нормально. Я пока ничего не менял.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this