使用 Jquery BlueImp 上传器上传大文件后出现延迟
Delay after uploading large files with Jquery BlueImp uploader
我能够通过 BlueImp Jquery 上传器插件成功上传大文件(测试最大 8GB)。
我的 PHP 设置是:
upload_max_filesize 8192M
post_max_size 8192M
max_execution_time 200
max_input_time 200
memory_limit 8192M
我遇到的问题是,当大文件(2GB 或更大)完成上传时,进度条停留在 100% 并且需要相当长的时间才能 "finish"。
我不确定 post 正在处理什么,除了将文件块拼凑在一起。
我已经尝试调整 UploadHandler.php 文件中的块大小,当增加时它似乎会稍微改善(例如从 10mb 到 500mb 块)但延迟仍然存在。完全禁用分块上传时似乎没有任何改进 (0),而且我不确定这样做的潜在后果。
对于 2gb 的文件,延迟大约为 20 秒,但对于 4gb 的文件,延迟大约为 2 分钟。一个 7gb 的文件大约需要 3-4 分钟,有时会超时。这让用户等待,不知道发生了什么,因为此时进度条已完成 100%。
有没有人知道这可能是什么,或者如何解决它?我怀疑 /tmp 中的文件可能被复制而不是移动,但据我所知,php 文件中没有这种迹象。
在我的服务器 VM 上提升 CPU 和 RAM 会稍微改善一些情况,尽管在此过程中 运行 "top" 命令显示 CPU 和 RAM 不会t 似乎非常疲惫(0-2%,与实际上传期间的 90-100% 相比)。
非常感谢。
我不太了解,我在 google 上搜索并找到了一些,我认为它可能对您有所帮助。
一般情况下,当服务器或客户端发生异常时,会触发“onError”事件。在上述情况下,直到服务器本身没有超时才会抛出异常。
一种可能是监控上传状态并在上传事件中设置JavaScript超时或计数器,在达到时间限制后将取消上传。
此处显示所有上传状态和错误代码 - http://help.infragistics.com/NetAdvantage/jQuery/2013.1/CLR4.0?page=igUpload_Using_Client_Side_Events.html
您可以在上传事件中使用“fileStatus”参数监控这些。
Link哪个对你有帮助
这可能是什么:
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 打印信息并检查浏览器的控制台输出。
解决方法:
如果您只想查看是否所有下载都已完成并向用户显示某些内容仍在继续,您可能需要查看停止/完成事件,或者还需要 fileupload('active') ,请看这里:Finish of Multiple file upload
在对这个问题进行了大量的故障排除和调试之后,我找到了我认为的原因,并且找到了更好的 workaround/solution。这有点“hacky”(我是业余开发者!),所以我愿意接受任何改进建议,尽管它似乎对我有用。
从客户端上传的文件实际上是上传到服务器上的这个临时位置:
/tmp/systemd-private-随机数-httpd.service-随机数/tmp/sess_php-session-ID
在客户端完成上传后,UI 进度条达到 100%,并在服务器处理文件时保持此状态。
服务器端的处理涉及将文件从上面的 /tmp 位置移动(复制,然后删除)到相关的 blueimp 位置。 (假设“user_dirs”在blueimp选项中是enabled/true,默认目的地是:/var/www/html/server/php/files/php-session-id / ).
此复制过程可能会花费大量时间,尤其是对于大于 2gb 或左右的文件。服务器处理完成后,blueimp 触发“fileuploaddone”回调,UI 更新为完成状态。
我的目标是在此时提供一些交互式 UI 反馈(而不是像其他解决方法那样挂在 90%)。我的环境能够上传非常大的文件 (10gb+),所以我觉得不为可能需要几分钟的文件处理(用户认为网站崩溃,关闭浏览器等)提供任何用户反馈是不可接受的.).
我的解决方法:
我遇到的第一个问题是客户端文件上传完成,服务端处理开始的时候,似乎没有blueimp回调。所以我通过创建一个函数(在 main.js 中)来解决这个问题,以在 data.loaded 匹配 data.total:
之后显示我的自定义“处理 div”
$('#fileupload').bind('fileuploadprogressall', function (e, data) { console.log(data);
if (data.loaded == data.total) {
setTimeout(function(){
$("#processwarn").fadeTo(300, 1);
},3000);
}})
我的自定义 div 位于进度条信息下方,是另一个 php 页面,每隔几秒刷新一次(使用 ajax.load)并计算所有文件的总文件大小当前会话上传文件夹中的文件(目录总大小似乎没有提供准确的结果):
// 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\"> Please wait, processing files: $total";
结果看起来像这样:
编辑:(经过更多工作)- 添加了 bootstrap 进度条:
测试中注意到的补充点:
启用分块(例如设置为 1gb (maxChunkSize: 1000000000) ),问题几乎消失了,因为处理时间对用户来说似乎大大减少了,因为 "copying" 处理发生在分块(本例中为每 1gb)。
当最后的处理发生时,服务器只需要 "rechunk"/复制最后剩下的 1gb。
因此,我也体验到了更快的整体上传时间。
事后看来,这对许多人来说可能是 easier/more 有效的解决方案。
我能够通过 BlueImp Jquery 上传器插件成功上传大文件(测试最大 8GB)。
我的 PHP 设置是:
upload_max_filesize 8192M
post_max_size 8192M
max_execution_time 200
max_input_time 200
memory_limit 8192M
我遇到的问题是,当大文件(2GB 或更大)完成上传时,进度条停留在 100% 并且需要相当长的时间才能 "finish"。 我不确定 post 正在处理什么,除了将文件块拼凑在一起。
我已经尝试调整 UploadHandler.php 文件中的块大小,当增加时它似乎会稍微改善(例如从 10mb 到 500mb 块)但延迟仍然存在。完全禁用分块上传时似乎没有任何改进 (0),而且我不确定这样做的潜在后果。
对于 2gb 的文件,延迟大约为 20 秒,但对于 4gb 的文件,延迟大约为 2 分钟。一个 7gb 的文件大约需要 3-4 分钟,有时会超时。这让用户等待,不知道发生了什么,因为此时进度条已完成 100%。
有没有人知道这可能是什么,或者如何解决它?我怀疑 /tmp 中的文件可能被复制而不是移动,但据我所知,php 文件中没有这种迹象。
在我的服务器 VM 上提升 CPU 和 RAM 会稍微改善一些情况,尽管在此过程中 运行 "top" 命令显示 CPU 和 RAM 不会t 似乎非常疲惫(0-2%,与实际上传期间的 90-100% 相比)。
非常感谢。
我不太了解,我在 google 上搜索并找到了一些,我认为它可能对您有所帮助。
一般情况下,当服务器或客户端发生异常时,会触发“onError”事件。在上述情况下,直到服务器本身没有超时才会抛出异常。
一种可能是监控上传状态并在上传事件中设置JavaScript超时或计数器,在达到时间限制后将取消上传。
此处显示所有上传状态和错误代码 - http://help.infragistics.com/NetAdvantage/jQuery/2013.1/CLR4.0?page=igUpload_Using_Client_Side_Events.html
您可以在上传事件中使用“fileStatus”参数监控这些。
Link哪个对你有帮助
这可能是什么:
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 打印信息并检查浏览器的控制台输出。
解决方法:
如果您只想查看是否所有下载都已完成并向用户显示某些内容仍在继续,您可能需要查看停止/完成事件,或者还需要 fileupload('active') ,请看这里:Finish of Multiple file upload
在对这个问题进行了大量的故障排除和调试之后,我找到了我认为的原因,并且找到了更好的 workaround/solution。这有点“hacky”(我是业余开发者!),所以我愿意接受任何改进建议,尽管它似乎对我有用。
从客户端上传的文件实际上是上传到服务器上的这个临时位置: /tmp/systemd-private-随机数-httpd.service-随机数/tmp/sess_php-session-ID
在客户端完成上传后,UI 进度条达到 100%,并在服务器处理文件时保持此状态。
服务器端的处理涉及将文件从上面的 /tmp 位置移动(复制,然后删除)到相关的 blueimp 位置。 (假设“user_dirs”在blueimp选项中是enabled/true,默认目的地是:/var/www/html/server/php/files/php-session-id / ).
此复制过程可能会花费大量时间,尤其是对于大于 2gb 或左右的文件。服务器处理完成后,blueimp 触发“fileuploaddone”回调,UI 更新为完成状态。
我的目标是在此时提供一些交互式 UI 反馈(而不是像其他解决方法那样挂在 90%)。我的环境能够上传非常大的文件 (10gb+),所以我觉得不为可能需要几分钟的文件处理(用户认为网站崩溃,关闭浏览器等)提供任何用户反馈是不可接受的.).
我的解决方法:
我遇到的第一个问题是客户端文件上传完成,服务端处理开始的时候,似乎没有blueimp回调。所以我通过创建一个函数(在 main.js 中)来解决这个问题,以在 data.loaded 匹配 data.total:
之后显示我的自定义“处理 div”$('#fileupload').bind('fileuploadprogressall', function (e, data) { console.log(data);
if (data.loaded == data.total) {
setTimeout(function(){
$("#processwarn").fadeTo(300, 1);
},3000);
}})
我的自定义 div 位于进度条信息下方,是另一个 php 页面,每隔几秒刷新一次(使用 ajax.load)并计算所有文件的总文件大小当前会话上传文件夹中的文件(目录总大小似乎没有提供准确的结果):
// 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\"> Please wait, processing files: $total";
结果看起来像这样:
编辑:(经过更多工作)- 添加了 bootstrap 进度条:
测试中注意到的补充点:
启用分块(例如设置为 1gb (maxChunkSize: 1000000000) ),问题几乎消失了,因为处理时间对用户来说似乎大大减少了,因为 "copying" 处理发生在分块(本例中为每 1gb)。
当最后的处理发生时,服务器只需要 "rechunk"/复制最后剩下的 1gb。
因此,我也体验到了更快的整体上传时间。
事后看来,这对许多人来说可能是 easier/more 有效的解决方案。