-
Notifications
You must be signed in to change notification settings - Fork 94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Не удаляется файл блокировки (падает процесс аггрегации) .../AggregateCommand.php.lock file #61
Comments
File AggregateCommand.php.lock creates in the begin of aggregate command and deleted at the end of this command. If it don't removed, other aggregate command is running or last execution failed. |
(можно по русски? Язык сломаю объяснять) |
Этот файл создается вначале команды агрегации и должен удаляться в конце. Он создается на случай, если параллельно решили запустить еще один command, или если команда сломалась, чтобы больше не запускалась сломанная команда. Может у тебя часто запускается это крон и они накладываются? |
Это я понял, что он создаётся и должен удаляться. Но отработка при ручном запуске происходит в течении 1-2 секунд - т.е. всё ОК. Крон стоит раз в 5 минут - т.е. тут вообще не должно быть проблем. Но вот случается, что то и файлик не удаляется. |
у меня тоже раз в пару дней такое случалось, я добавил в cron |
это проблема самого пхп. видать что-то падает. и потому стоит использовать posix_kill.
|
@gotlium, а почему |
Пример из доки. Объясню: Вы сохраняете pid процесса в файл, после пытаетесь проверить запущен ли процесс с таким PID, и если не запущен, то в этом случае запускаете команду. |
Мне хотелось бы вставить своих 5 копеек, и предостеречь вас от необдуманных решениях подобного рода. В юникс системах для процессов, которые не должны запускатся конкурентно, если этот процесс запускается но одном хосте - принято использовать flock Использование достаточно тривиально: (
flock -n 9 || exit 1
pinba-console aggregate # your command here
) 9>/var/lock/mylockfile PHP класс который мы используем в продакшине для этих целей /**
* @example
* <code>
* $flock = new FLock(__CLASS__);
* if(!$flock->isLocked()){
* $output->writeln("<error> Command ". $this->getName(). " already running in this system. Kill it or try again later </error>", OutputInterface::VERBOSITY_QUIET);
* return -1;
* }
* </code>
* This class wont work in case of php segfault.
*/
class FLock {
private $_lock = null;
private $_lockfilepath = null;
private $_is_locked = false;
public function __construct($lock_name, $throw_exception = false) {
$this->_lockfilepath = "/dev/shm/" . md5($lock_name);
$this->_lock = fopen($this->_lockfilepath, "w+");
if ( ! $this->_lock ) {
throw new \Exception("Could not create lock file for writing " . $this->_lockfilepath);
}
$this->_is_locked = flock($this->_lock, LOCK_NB + LOCK_EX);
if ($this->_is_locked) {
ftruncate($this->_lock, 0);
fwrite($this->_lock, posix_getpid());
fflush($this->_lock);
} else if ( $throw_exception ) {
throw new \Exception("Could not acquire exclusive lock for " . $lock_name);
}
}
public function isLocked() {
return $this->_is_locked;
}
public function __destruct() {
if ( $this->_lock && $this->_is_locked ) {
flock($this->_lock, LOCK_UN);
unlink($this->_lockfilepath);
}
}
} Flock однако не поможет если необходимо запретить конкурентный запуск программы в кластере (более чем на одном хосте). В этом случае вам придется искать решения в виде реализации семафоров на базе memcache/redis
|
@mbIkola А в каких ситуациях текущий механизм не срабатывал? Хочется выяснить, я ни разу не сталкивался с этой проблемой и не могу ее воспроизвести. |
Ну дык, как и описано в самом начале - проблемы возникали когда AggregateCommand.php.lock оставался после работы скрипта (неудалялся) |
А почему обернули flock-ом в кронтабе, а не внутри через $flock = new FLock(__CLASS__);
if(!$flock->isLocked()){
$output->writeln("<error> Command ". $this->getName(). " already running in this system. Kill it or try again later </error>", OutputInterface::VERBOSITY_QUIET);
return -1;
} Так в принципе нельзя или просто сделали как побыстрее? |
Я к тому, что можно это внедрить в Pinboard, чтобы работало из коробки :) |
это подразумевает модификацию кода пинборды. Стоит так же учесть что FLock отанлочит лок файл в случае сегфолта/killall -9 только на линукс системах (ядро релизит все локи в процессе закрытия файловых дескрипторов, что происходит вроде как автоматически). FLock не использовался ибо : необходимо редачить код пинбы (это дольше чем удалить пару строк из AggregateCommand и требует небольших навыков), и я не очень уверен даже в своем пхп коде. Просто потому что пхп, и люди бывает ошибаются. |
Ок, я изучу детальнее данный подход. В целом он мне импонирует. Если у кого-то есть мысли по поводу подводных камней использования Flock, то велкам. |
@mobilesfinks у меня будет просьба все же попробовать выяснить из-за чего падает aggregate. Можешь в файле console раскомментировать строки //ini_set('display_errors', 'on');
//$app['debug'] = true; и в команду крона добавить, чтобы получилось примерно так:
И когда снова возникнет ситуация с неудаленным локом скинуть мне содержимое логов. |
Включил логгирование, вот что выдало в ошибку
По поводу того как убивать файл - flock мне не помогает, сейчас заметил, что аггрегирование не работало нормально с момента как в крон поставил
|
Может тебе прописать что-то подобное |
Ребят, а у остальных такая же ошибка? Я так понимаю, все упирается в количество подключений через сокет, подключение по tcp должно решать эту проблему. |
Не помогло |
Это уже другая ошибка. У тебя стоят настройки типа:
? |
Настройки чего? |
Эта ошибка возникает постоянно или периодически? |
Если постоянно удаляется файл блокировки, то её не возникает. Как только отключаю принудительное удаление, через несколько запусков эта ошибка и аггрегация блокируется файлом блокировки. |
А точно не возникает? Можешь сделать на кроне и удаление лока, и запись логов? |
Возникает, но не часто. Сейчас добавил дату в лог ошибок, посмотрю как часто будет сыпатья. Отпишусь попозже. |
В общем ситуация такая: UPD: |
UPD2: У нас на гипервизорах для более плотного размещения виртуалок используется скрипт динамического контроля памяти виртуальных машин. Каждый раз когда он отрабатывает mysql крашится и перезапускается. Именно в этот момент отрабатывает аггрегатор - после падения mysql аггрегатор сам падает. Вышеуказанный скрипт запускается каждые 10 минут. Падение mysql я могу избежать увеличением выделения оперативной памяти виртуальной машине. |
Я думаю, правильнее сделать в начале агрегации что-то вроде проверки коннекта к mysql, и завершать работу (удаляя lock-файл), если коннекта нет. В остальных случаях текущая логика с lock-файлом мне кажется корректной. Можно еще сделать отправку письма на служебную почту, если пинбоард натыкается на lock-файл. |
Согласен. |
Пока в мастере, после закрытия еще пары задач сформирую v1.2
|
After some time cant see data in web.
After try start Crontab task manually get error:
Cannot run data aggregating: the another instance of this script is already executing. Otherwise, remove /var/www/pinboard/src/Pinboard/Command/AggregateCommand.php.lock file
but nothing running at this time.
to resolve this issue, to the end of aggregate command in crontab add
&& rm -rf /%PATH_to_lockFIle%/AggregateCommand.php.lock
pinboard v.1.1
The text was updated successfully, but these errors were encountered: