Ограничить количество экземпляров Symfony Command
У меня есть команда в моем приложении Symfony, запущенном Cron. Я хочу иметь возможность ограничить количество одновременно выполняемых экземпляров на моем сервере, скажем, 4 экземпляра. Я понятия не имею, как это сделать. Я нашел, как заблокировать команду, чтобы запустить команду только один раз и дождаться ее завершения, но я не знаю, как запустить более одного и все равно ограничить количество экземпляров. У тебя есть идея?
4 ответа
То, что вы ищете, это semaphore
,
E сть LockComponent
на данный момент запланировано 3,4 (был снят с 3,3). Это значительное улучшение по сравнению с LockHandler
в FilesystemComponent
,
В крайнем случае, вы, вероятно, можете объединить фиксированное количество блокировок из LockHandler
, Я не рекомендую это, потому что он использует flock
в файловой системе. Это ограничивает блокировку одним сервером. Дополнительно, flock
может быть ограничено областью процесса в некоторых системах.
<?php
use Symfony\Component\Filesystem\LockHandler;
define('LOCK_ID', 'some-identifier');
define('LOCK_MAX', 5);
$lockPool = [];
for ($i = 0; $i <= LOCK_MAX;) {
$lockHandle = sprintf('%s-%s.lock', LOCK_ID, ++$i);
$lockPool[$i] = new LockHandler($lockHandle);
}
$activeLock = null;
$lockTimeout = 60 * 1000;
$lockWaitStart = microtime(true);
while(!$activeLock) {
foreach ($lockPool as $lockHandler) {
if ($lockHandler->lock()) {
$activeLock = $lockHandler;
break 2;
}
}
if ($lockTimeout && ($lockTimeout > microtime(true) - $lockWaitStart)) {
break;
}
// Randomly wait between 0.1ms and 10ms
usleep(mt_rand(100, 10000));
}
Гораздо лучшим и эффективным решением было бы использовать расширение семафора и поработать с волшебством ftok
, shm_*
а также sem_*
,
Вы можете использовать файл с общим счетчиком, который содержит счетчик, который увеличивается при запуске команды и уменьшает его до завершения.
Другим решением будет проверка списка процессов с чем-то вроде этого:
$processCount = exec('ps aux | grep "some part of the console command you run" | grep -v "grep" | wc -l' );
if(!empty($processCount) && $processCount >= X) {
return false;
}
Вы можете создать "команду запуска", выполняемую вашим cron или супервизором.
Эта запятая Symfony может запускать ваши экземпляры с компонентом процесса на вашем сервере. Вы также можете проверить все, что вы хотите проверить, и сделать все, что вы хотите сделать, как exec
функция php.
Я предлагаю вам использовать систему управления процессами в качестве руководителя. его довольно просто использовать, и вы можете выбрать, сколько экземпляров вашего скрипта вы запускаете.