这很奇怪,我搜索并尝试了所有内容,但我认为我只是在这里犯了一个愚蠢的语法错误。
我试图在CPU上运行压力测试,然后通过PHP立即将其CPU使用率限制为30%。该测试也在另一个用户下运行,并且具有指定的名称,因此可以对其进行限制。压力测试开始很好,但我可以看到PHP文件仍在加载,并且它结束了压力测试结束的第二个。
以下是我尝试过的一些方法
$output = exec('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30"');
$output = exec('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s > /dev/null & cpulimit -e MyUniqueProcessName -l 30"');
这样做的全部目的是因为我正在为游戏托管网站编写脚本,我想限制每台服务器的资源消耗以提高质量,而不是让某人占用所有资源。 基本上,游戏服务器将运行而不是压力测试。
编辑::
这就是我现在所拥有的:
我需要在"测试"下运行压力。 ,但是在sudo apache或root下的cpulimit,因为它需要特殊权限。压力仍然开始很好,但它吃了99.9%
passthru('sudo runuser -l test -c "exec -a MyUniqueProcessName stress -c 1 -t 60s &" & sudo cpulimit -e MyUniqueProcessName -l 30 -i -z');
执行此操作后,我无法在流程列表中看到cpulimit http://i.imgur.com/iK2nL43.png
答案 0 :(得分:0)
不幸的是,&&
或多或少与您想要的相反。 :-)当你在Bash中A && B
时,这意味着,"运行命令A并等到它完成;如果成功,则运行命令B。"
相比之下,A & B
表示,"运行命令A,然后立即运行命令B."
所以你在你的命令中接近正确,但只是使用两个bash
命令(应该只需要一个)和&&
来绊倒。
另外,您是否尝试在两个终端中在PHP之外单独运行每个命令?我刚刚下载并构建了stress和cpulimit(我假设这些是您正在使用的?),单独运行命令,并发现问题:cpulimit
仍然不是&{限制百分比。
查看stress
的文档,我发现它可以通过分支子进程来工作,因此您尝试CPU限制的那个是父进程,但那不是使用的进程CPU。 cpulimit --help
显示了-i
选项,其中包含有限的子进程。
这让我能够在一个终端输入此内容(第一行显示提示输入;后续显示输出):
$> exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30 -i
[1] 20229
MyUniqueProcessName: info: [20229] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
Process 20229 found
然后,在另一个运行top
的终端中,我看到了:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20237 stackov+ 20 0 7164 100 0 R 30.2 0.0 0:04.38 stress
好多了。 (请注意,在使用exec -a
对其进行别名的Bash shell之外,您会看到进程名称为stress
。)不幸的是,我还看到另一个问题,即剩余cpulimit
&# 34;听音"用于具有该名称的更多进程。返回cpulimit --help
,其中显示-z
选项。
只是为了降低复杂性,你可以通过特殊的Bash变量stress
来关闭别名并使用$!
进程的PID,它引用最后一个进程的PID推出。在终端中运行以下内容似乎可以完成您想要的一切:
stress -c 1 -t 60s & cpulimit -p $! -l 30 -i -z
现在,只需使用我们学到的知识更改PHP脚本:
exec('bash -c "exec -a MyUniqueProcessName stress -c 1 -t 60s & cpulimit -e MyUniqueProcessName -l 30 -i -z"');
......或更简单的版本:
exec('bash -c "stress -c 1 -t 60s & cpulimit -p \$! -l 30 -i -z"');
(请注意$!
中的$必须使用反斜杠\$!
进行转义,因为它在传递给bash -c
时的引用方式。)
最终答案:
根据你修改问题的最后一个例子,你会想要这样的事情:
passthru('bash -c "sudo -u test stress -c 1 -t 60s & sudo -u root cpulimit -p \$! -l 30 -i -z"');
当我使用php stackoverflow-question.php
运行时,会输出以下内容:
stress: info: [3374] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
stress: info: [3374] successful run completed in 60s
Process 3371 found
(在PHP脚本完成后,第二行仅出现,所以不要误导。使用top
进行检查。)
在PHP脚本运行的60秒内在另一个终端运行top
,我看到了:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3472 test 20 0 7160 92 0 R 29.5 0.0 0:07.50 stress
3470 root 9 -11 4236 712 580 S 9.0 0.0 0:02.28 cpulimit
这正是您所描述的想法:stress
正在用户test
下运行,而cpulimit
正在用户root
下运行(两者都是如果需要,您可以在命令中更改)。 stress
限制在30%左右。
我不熟悉runuser
并且没有看到适用性,因为sudo
是以另一个用户身份运行流程的标准方式。要使其工作,您可能必须在/ etc / sudoers中调整您的设置(这将需要root访问权限,但您显然已经拥有了该设置)。这完全超出了本次讨论的范围,但作为一个例子,我添加了以下规则:
my-user ALL=(test) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/stress
my-user ALL=(root) NOPASSWD:NOEXEC: /home/my-user/development/stackoverflow/cpulimit