PHP 被细节吓坏了
PHP fread by detail
请查看下面的 PHP 代码。它来自下载脚本:
while(ob_get_level() > 0){
ob_end_clean();
}
set_time_limit(0);
ignore_user_abort(true);
$file = fopen(MATIN_FILE_PATH,"rb"); // the main file
$chunksize = 2*1024*1024;
while(!feof($file)){
echo @fread($file, $chunksize);
flush();
if (connection_status() == 1){ // if client aborted
@fclose($file);
exit;
}
}
@fclose($file);
exit;
在此代码中,您看到我每个块发送 2 MB。
想象一个速度为 100kb/s
的客户端
经过多次调试,我发现当客户端每下载2MB时,会出现fwrite
,while
进入下一个循环。那么,PHP此时在做什么呢?是不是等用户下载完2MB再发送2MB?所以,我发送每个块 10MB 或 50MB 不是更好吗?
感谢您提供任何详细指南。
假设您同时有 10 个客户端请求使用此脚本下载某些文件,并且您已将每个块大小设置为 50MB。对于每个请求,都会调用一个新的 php 进程,每个请求都需要 50MB 的服务器内存来处理 fread($file, 50*1024*1024)
。因此,您将消耗 500MB 的内存。
如果像您建议的那样,客户端速度是 100kb/s,那么您有 100 个并发连接的可能性并没有那么低,您可以获得 100 个并发请求,这已经是 5GB 的 RAM。你有那么多还是需要那么多?
您不能让用户下载文件的速度超过他的实际下载速度,因此块大小对此无关紧要。减少循环迭代次数都无助于加快速度。我没有对此进行测试,但我认为,循环的执行速度比远程客户端的 I/O 操作快。因此,您真正应该关心的唯一一件事就是让您的服务器可靠地工作。
请查看下面的 PHP 代码。它来自下载脚本:
while(ob_get_level() > 0){
ob_end_clean();
}
set_time_limit(0);
ignore_user_abort(true);
$file = fopen(MATIN_FILE_PATH,"rb"); // the main file
$chunksize = 2*1024*1024;
while(!feof($file)){
echo @fread($file, $chunksize);
flush();
if (connection_status() == 1){ // if client aborted
@fclose($file);
exit;
}
}
@fclose($file);
exit;
在此代码中,您看到我每个块发送 2 MB。
想象一个速度为 100kb/s
的客户端
经过多次调试,我发现当客户端每下载2MB时,会出现fwrite
,while
进入下一个循环。那么,PHP此时在做什么呢?是不是等用户下载完2MB再发送2MB?所以,我发送每个块 10MB 或 50MB 不是更好吗?
感谢您提供任何详细指南。
假设您同时有 10 个客户端请求使用此脚本下载某些文件,并且您已将每个块大小设置为 50MB。对于每个请求,都会调用一个新的 php 进程,每个请求都需要 50MB 的服务器内存来处理 fread($file, 50*1024*1024)
。因此,您将消耗 500MB 的内存。
如果像您建议的那样,客户端速度是 100kb/s,那么您有 100 个并发连接的可能性并没有那么低,您可以获得 100 个并发请求,这已经是 5GB 的 RAM。你有那么多还是需要那么多?
您不能让用户下载文件的速度超过他的实际下载速度,因此块大小对此无关紧要。减少循环迭代次数都无助于加快速度。我没有对此进行测试,但我认为,循环的执行速度比远程客户端的 I/O 操作快。因此,您真正应该关心的唯一一件事就是让您的服务器可靠地工作。