我想对使用 popen 在 PHP 中打开的 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);
过程如下:
- 浏览器发送一个 GET 请求,等待 HTML5 服务器端事件格式的应答。
- 该请求由 AWS 负载均衡器接收并转发到 EC2 实例。
- 答案是文件的最后 30 行
- 浏览器在 30 条消息中收到它,并且连接保持不变。
- 如果 tail 命令发送一个新行,则返回,否则 fgets 等待未定义的时间,直到从 tail 命令返回新行。
- AWS 负载均衡器在网络不活动 60 秒后(60 秒内没有新行)关闭与浏览器的连接。与 EC2 实例的连接未关闭。
- 浏览器检测到连接已关闭并打开一个新连接,过程返回步骤 1。
正如这个步骤所描述的,AWS 负载均衡器和 EC2 实例之间的连接永远不会关闭,几个小时/几天后,有成百上千的 tail 和 httpd 进程在运行,服务器开始没有响应。
当然,这似乎是一个 AWS 负载均衡器错误,但我不想启动一个流程来获得亚马逊的关注并等待修复。
我的临时解决方案是在服务器变得不稳定之前执行 sudo kill tail 来终止进程。
我认为 PHP 不会停止脚本,因为 PHP 被“阻止”等待 fgets 完成。
我知道 AWS 负载均衡器的时间限制是可编辑的,但我想保持默认值,即使更高的限制也无法解决问题。
我不知道是否需要将问题更改为如何在 linux 中执行具有时间限制/超时的进程?。
PHP 5.5.22 / Apache 2.4 / Linux 内核 3.14.35-28.38.amzn1.x86_64