2017-04-05 120 views
3

我能够通过BlueImp Jquery Uploader插件成功上传大文件(测试最多8GB)。使用Jquery BlueImp上传器上传大文件后延迟

我的PHP设置:

upload_max_filesize 8192M 
post_max_size 8192M 
max_execution_time 200 
max_input_time 200 
memory_limit 8192M 

我遇到的问题是,当大文件(2GB或更大)完成上传,进度条挂在100%,需要相当长的时间来“完成” 。 我不确定发生了什么后期处理,除了将文件块拼接在一起。

我试着调整UploadHandler.php文件中的块大小,并且它在增加(例如从10mb到500mb大块)时似乎稍有改进,但延迟仍然存在。当完全禁用分块上传(0)时,似乎没有任何改进,我也不确定这样做的潜在影响。

对于一个2GB的文件,延迟大约是20秒,但是在一个4GB的文件上,大约2分钟。一个7GB的文件大约需要3-4分钟,有时会超时。这使用户等待,不知道当进度条在此时已完成100%时发生了什么。

有没有人有任何的洞察力,这可能是什么,或如何去解决它?我怀疑/ tmp中的文件可能被复制而不是移动,但根据我的说法,在php文件中没有任何迹象。

在我的服务器上增强CPU和RAM虚拟机可以改善一点,尽管在此过程中运行“top”命令表明CPU和RAM似乎不会被大量耗尽(0-2%,与90实际上传时为-100%)。

非常感谢提前。

+0

_The上传process_浏览器发送2gig到Apache,Apache的传递2gig到PHP,您的代码运行做了'move_uploaded_file()以'和移动2演出从一个目录到另一个。上传完成后至少会发生最后一部分 – RiggsFolly

+0

感谢您的回复。上传过程本身非常快,问题在于上传完成后。 “移动文件”操作会立即在命令行中执行。那么上传后实际发生什么情况会导致此延迟? – BSUK

回答

0

在对这个问题进行了大量的故障排除和调试之后,我发现了我认为是的原因以及更好的解决方法。这有点“哈克”(我是一个业余开发者!),所以我愿意提出任何改善这个问题的建议,尽管它似乎对我有用。

从客户端上传的文件实际上是上传到服务器上的此临时位置: 的/ tmp/systemd-私营随机数 -httpd.service- 随机数的/ tmp/sess_ PHP -session-ID

在客户端上传完成后,UI进度条会达到100%,并且在服务器正在处理这些文件时保持这种状态。

服务器端的处理包括将文件从上面的/ tmp位置移动(复制,然后删除)到相关的blueimp位置。 (假设在blueimp选项中启用了“user_dirs”,默认目的地是:/ var/www/html/server/php/files/php-session-id /)。

此复制过程可能会花费大量时间,特别是在大于2GB或大约2GB的文件上。一旦服务器处理完成,blueimp会触发“fileuploaddone”回调,UI将更新为完成状态。

我的目标是在此时提供一些交互式UI反馈(而不是像其他解决方法一样挂在90%)。我的环境能够上传非常大的文件(10GB +),所以我不认为不接受任何用户对文件处理可能需要几分钟的反馈(用户认为该网站崩溃并关闭浏览器等) )。

我的解决方法:

我遇到的是,当文件上传已经完成了在客户端和服务器的处理开始似乎没有成为一个点的blueimp回调的第一个问题。所以我通过创建一个函数(在main.js中)在data.loaded后匹配数据显示我的自定义“processing div”来解决此问题。总:

$('#fileupload').bind('fileuploadprogressall', function (e, data) { console.log(data); 
if (data.loaded == data.total) { 
setTimeout(function(){ 
$("#processwarn").fadeTo(300, 1); 
},3000); 
}}) 

我定制的div位于下方的进度条信息是进行刷新(用ajax.load)每隔几秒钟,并计算在当前会话中上传的所有文件的总文件大小另一个PHP页面文件夹(目录总规模似乎并没有提供准确的结果):

// Calculate size of files being processed 
$filePath = "/var/www/html/server/php/files/*php-session-id*/"; 

$total = 0; 
$d = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($filePath), 
    RecursiveIteratorIterator::SELF_FIRST 
); 

foreach($d as $file){ 
    $total += $file->getSize(); 
} 

// Convert to readable format 
if ($total >= 1073741824) 
{ 
    $total = number_format($total/1073741824, 2) . ' GB'; 
} 
elseif ($total >= 1048576) 
{ 
    $total = number_format($total/1048576, 2) . ' MB'; 
} 
elseif ($total >= 1024) 
{ 
    $total = number_format($total/1024, 2) . ' KB'; 
} 
elseif ($total > 1) 
{ 
    $total = $total . ' bytes'; 
} 
elseif ($total == 1) 
{ 
    $total = $total . ' byte'; 
} 
else 
{ 
    $total = '0 bytes'; 
} 

// Display spinner gif and size of file currently being processed 
echo "<img src=\"img/spinner.gif\" height=\"20px\" width=\"20px\">&nbsp;&nbsp;Please wait, processing files: &nbsp;&nbsp;$total"; 

结果看起来是这样的:

processing div

编辑:(后一些更多的工作) - 随着引导进度条补充,而不是:

bootstrap progress bars

附加点从测试中发现:

随着分块启用(例如设置为1GB(maxChunkSize :1000000000)),问题几乎消失,因为“复制”处理发生在分块点(本例中每1GB),处理时间显着减少到用户。 当最后的处理发生时,服务器只需“rechunk”/复制剩余的最后1GB。
由于此,我也经历了更快的总体上传时间。事后看来,这对许多人来说可能是更简单/更有效的解决方案。

0

我不太了解它,我在谷歌搜索,我发现了一些,我认为它可以帮助你。

通常情况下,当服务器或客户端发生异常时,会触发“onError”事件。在上述情况下,服务器本身没有超时之前不会抛出异常。

一种可能性是监视上传状态,并设置JavaScript超时或计数器上传事件,以便在达到时间限制后取消上传。

所有上传状态和错误代码显示在这里 - http://help.infragistics.com/NetAdvantage/jQuery/2013.1/CLR4.0?page=igUpload_Using_Client_Side_Events.html

您可以在上传事件“时间filestatus”的说法监控这些。

链接,这将有助于你

  1. Link1
  2. Link2
  3. Link3
0

什么,这可能是

jQuery FileUpload注册请求进度事件。这是浏览器向服务器发送数据时的事件,而不是来自服务器的确认事件。浏览器发送和服务器确认接收之间有延迟。有关这两个事件,请参阅Can onprogress functionality be added to jQuery.ajax() by using xhrFields?。然而,我无法为我解决这个问题并使用了解决方法,所以我不能完全确认这个假设。

如何去故障排除它:

使用浏览器的调试工具和代码在这里设置一个断点,以获取可用的变量的理解:一旦确定 https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L372

什么你想看,最好的情况是用console.log打印信息,并检查你的浏览器的控制台输出。

变通

如果你只看到感兴趣的所有下载是否完成,并显示给用户的东西仍在继续,你可能想看看停止/ DONE事件,或还有fileupload('active'),请看这里:Finish of Multiple file upload

相关问题