我希望对使用PHP中的popen打开的fget读取进程施加一个时间限制。
我有下一个代码:
$handle = popen("tail -F -n 30 /tmp/pushlog.txt 2>&1", "r");
while(!feof($handle)) {
$buffer = fgets($handle);
echo "data: ".$buffer."\n";
@ob_flush();
flush();
}
pclose($handle);
我试过但没有成功:
set_time_limit(60);
ignore_user_abort(false);
这一过程如下:
正如以下步骤所描述的,AWS负载均衡器和EC2实例之间的连接从未关闭过,在几个小时/天之后,有数百个尾和httpd进程在运行,服务器开始不应答。
当然,它似乎是一个AWS负载均衡器错误,但我不希望启动一个进程来赢得亚马逊的关注,等待修复。
我的临时解决方案是在服务器变得不稳定之前做一个sudo杀伤尾来杀死进程。
我认为PHP并没有停止脚本,因为PHP被“阻塞”了,等待fget完成。
我知道AWS负载均衡器的时间限制是可编辑的,但是我希望保持默认值,即使是更高的限制也不会解决这个问题。
我不知道是否需要将这个问题更改为如何在有时限/超时的linux中执行进程?
PHP 5.5.22 / Apache 2.4 / Linux内核3.14.35-28.amzn1.x86_64
发布于 2015-05-13 20:25:24
用PHP 5.5.20测试:
//Change configuration.
set_time_limit(0);
ignore_user_abort(true);
//Open pipe & set non-blocking mode.
$descriptors = array(0 => array('file', '/dev/null', 'r'),
1 => array('pipe', 'w'),
2 => array('file', '/dev/null', 'w'));
$process = proc_open('exec tail -F -n 30 /tmp/pushlog.txt 2>&1',
$descriptors, $pipes, NULL, NULL) or exit;
$stream = $pipes[1];
stream_set_blocking($stream, 0);
//Call stream_select with a 10 second timeout.
$read = array($stream); $write = NULL; $except = NULL;
while (!feof($stream) && !connection_aborted()
&& stream_select($read, $write, $except, 10)) {
//Print out all the lines we can.
while (($buffer = fgets($stream)) !== FALSE) {
echo 'data: ' . $buffer . "\n";
@ob_flush();
flush();
}
}
//Clean up.
fclose($stream);
$status = proc_get_status($process);
if ($status !== FALSE && $status['running'] === TRUE)
proc_terminate($process);
proc_close($process);
发布于 2015-05-14 06:55:28
我没有使用进程文件指针,而是采用了我的“多任务处理”方法。我使用这段代码生成其他“进程”,类似于一种多任务欺骗。
我调用一个脚本hang.php,它只挂起90秒:sleep(90)
。
您可能需要调整流和stream_select超时。
创建流
header('Content-Type: text/plain; charset=utf-8');
$timeout = 20;
$result = array();
$sockets = array();
$buffer_size = 8192;
$id = 0;
$stream = stream_socket_client("ispeedlink.com:80", $errno,$errstr, $timeout,
STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);
if ($stream) {
$sockets[$id++] = $stream; // supports multiple sockets
$http = "GET /testbed/hang.php HTTP/1.0\r\nHost: ispeedlink.com\r\n\r\n";
fwrite($stream, $http);
}
else {
echo "$id Failed\n";
}
可以通过添加流:$sockets[$id++] = $stream;
来运行其他脚本
下面将向$result[$id]
数组中读取任何内容。
监视流:
while (count($sockets)) {
$read = $sockets;
stream_select($read, $write = NULL, $except = NULL, $timeout);
if (count($read)) {
foreach ($read as $r) {
$id = array_search($r, $sockets);
$data = fread($r, $buffer_size);
if (strlen($data) == 0) { // either reads data or EOF
echo "$id Closed: " . date('h:i:s') . "\n\n\n";
fclose($r);
unset($sockets[$id]);
}
else {
$result[$id] .= $data;
}
}
}
else {
echo 'Timeout: ' . date('h:i:s') . "\n\n\n";
break;
}
}
echo system('ps auxww');
。
当我想要终止一个进程时,我使用system('ps auxww')
获取pid并使用system("kill $pid")
终止它。
kill.php
header('Content-Type: text/plain; charset=utf-8');
//system('kill 220613');
echo system('ps auxww');
https://stackoverflow.com/questions/30227531
复制相似问题