我的 Symfony 应用程序中有一个由 Cron 启动的命令。我希望能够限制在我的服务器上同时执行的实例数,比如说 4 个实例。我不知道如何做到这一点。我找到了如何锁定命令以仅启动一次命令并等待它完成,但我不知道如何启动多个并限制实例数量。你有想法吗 ?
问问题
432 次
4 回答
1
您正在寻找的是一个semaphore
.
目前有一个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_*
.
于 2017-10-12T11:03:09.527 回答
0
我建议您使用过程控制系统作为主管。它使用起来非常简单,您可以选择启动多少个脚本实例。
于 2017-10-11T20:45:09.377 回答
0
您可以使用一个共享计数器文件,该文件包含一个计数器,该计数器在命令开始运行时增加并在完成之前减少它。
另一种解决方案是检查进程列表,如下所示:
$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;
}
于 2017-10-12T07:51:19.633 回答
0
您可以创建由您的 cron 或主管执行的“启动器命令”。
这个 Symfony commad 可以使用服务器上的进程组件启动您的实例。您还可以检查您想要检查的任何内容并执行您想要执行的所有操作,例如exec
php 函数。
于 2017-10-12T09:10:32.247 回答