Ограничить количество экземпляров 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.

Я предлагаю вам использовать систему управления процессами в качестве руководителя. его довольно просто использовать, и вы можете выбрать, сколько экземпляров вашего скрипта вы запускаете.

http://supervisord.org/

Другие вопросы по тегам