限制Symfony Command的实例数

时间:2017-10-11 18:03:58

标签: symfony cron symfony-console

我在Cron推出的Symfony应用程序中有一个命令。我希望能够限制在我的服务器上同时执行的实例数,让我们说4个实例。我不知道如何做到这一点。我发现如何锁定命令只启动命令一次并等待它完成,但我不知道如何启动多个并且无论如何限制实例数。 你有什么想法吗?

4 个答案:

答案 0 :(得分:1)

您要找的是semaphore

目前有一个LockComponent预定为3.4(从3.3中拉出)。这是对LockHandlerFilesystemComponent的重大改进。

在紧要关头,您可以从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));
}

一个更好,更有效的解决方案是使用信号量扩展,并与ftokshm_*sem_*合作。

答案 1 :(得分:0)

我建议您使用过程控制系统作为主管。它使用起来非常简单,您可以选择启动脚本的实例数。

http://supervisord.org/

答案 2 :(得分:0)

您可以使用共享计数器文件,该文件包含一个在Command开始运行时增加的计数器,并在它完成之前减少它。

另一个解决方案是使用以下内容检查进程列表:

$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;
}

答案 3 :(得分:0)

您可以创建由您的cron或主管执行的“启动器命令”。

此Symfony commad可以使用您服务器上的process component启动您的实例。您还可以检查要检查的内容,并执行您想要执行的所有操作,例如exec php函数。