新手问题 请教一个大文件上传速度缓慢的问题 (已解决)

hexawing · 2016年05月23日 · 最后由 hexawing 回复于 2017年04月28日 · 3411 次阅读

问题描述是: 从局域网 A 电脑传到 B 电脑。

10k 的文件,上传耗时 37 毫秒

41M 的文件,上传耗时 21.8 秒

175M 的文件,上传耗时……4.9 分钟………………

class UploadedFile < ApplicationRecord
  def self.create_with(params, user_id)
    file = params[:files]
    file_data = file.read
    url = "#{Rails.root}/public/files/upload/#{file.original_filename}"
    File.open(url, 'wb+') {
        |f| f.write(file_data)
    }
    uploaded_file = create(
        {
            :description => params[:fileDescription],
            :name => file.original_filename,
            :user_id => user_id,
            :url => "files/upload/#{file.original_filename}",
            :size => File.size(url),
            :sha_code => Digest::SHA2.hexdigest(file_data),
            :mime_type => file.content_type,
            :thumbnail_url => nil
        }
    )
    file_id = uploaded_file[:id]
    return {:file_id => file_id}
  end
end

看了下 log,大概这样:

Started POST "/sampling_requirement/upload_save" for 172.18.5.44 at 2016-05-22 15:33:35 +0800
Cannot render console from 172.18.5.44! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by SamplingRequirementController#upload_save as */*
  Parameters: {"fileDescription"=>"", "authenticity_token"=>"wh6n1sgPgyBhs+1HMXGlyNd809kCblTpY2hzxQ7O9VAptFFYF7LvW+N+zzGgwiaun7AUKEFobt5gw08KdsNP3A==", "files"=>#<ActionDispatch::Http::UploadedFile:0x007f96c600cf08 @tempfile=#<Tempfile:/tmp/RackMultipart20160522-3838-jpi4q1.pdf>, @original_filename="Ruby元编程中文版.pdf", @content_type="application/pdf", @headers="Content-Disposition: form-data; name=\"files\"; filename=\"Ruby\xE5\x85\x83\xE7\xBC\x96\xE7\xA8\x8B\xE4\xB8\xAD\xE6\x96\x87\xE7\x89\x88.pdf\"\r\nContent-Type: application/pdf\r\n">}
  [1m[35m (25.8ms)[0m  [1m[35mBEGIN[0m
  [1m[35mSQL (29.9ms)[0m  [1m[32mINSERT INTO `uploaded_files` (`name`, `url`, `description`, `size`, `sha_code`, `mime_type`, `user_id`, `created_at`, `updated_at`) VALUES ('Ruby元编程中文版.pdf', 'files/upload/Ruby元编程中文版.pdf', '', 47186322, 'dfedd6c8b0a0fdceb9dc63d1ad26caf27b16491ecc14347cbe4d4a4cdd0f8620', 'application/pdf', 1, '2016-05-22 07:33:37', '2016-05-22 07:33:37')[0m
  [1m[35m (43.8ms)[0m  [1m[35mCOMMIT[0m
Completed 200 OK in 1853ms (Views: 0.5ms | ActiveRecord: 99.5ms)

logger.info过每一步,发现其实后面每一步时间都不超过一秒。时间方面,那 4.9 分钟里,大约有 4.8 分钟在等这条 log 出来,出来之后后面的进展就很流畅了…… 求解 T_T

这么大的文件上传 可以放异步队列里上传。就是 f.open 的 write 操作慢。如果不是用异步方式,应该有一些前端的 js 方法 显示进度条,可以找个在前端显示

#1 楼 @pathbox 请教一下“异步队列”要怎么搞?谢谢! 前台同不同步显示的问题可以忽略,只要时间正常点就行……局域网 100 来兆的文件,拷贝的话也要不了一分钟吧

可以考虑用 nginx 处理文件上传请求,上传完毕以后调用 rails 页面处理上传的临时文件

#3 楼 @alucardpj nginx……我去搜搜…………谢谢

搁置了一年的问题,又拿出来问了…… 最近才有时间搜了一下 nginx upload 的方案,不过现在面临的最大问题是 upload module 它不更新了但 nginx 还在更新,所以新版本的用不了………………请问各位有好的解决方案吗?谢谢!

Nginx 用的 1.4.7(太高了不支持 upload module),但是还是打了个补丁:http://blog.csdn.net/igame/article/details/17477351 然后各种配置网上各种文章参考了一番,总算是能响应上传请求了,1G 的文件小于 1 分钟,再大了没试,应该也够用了……

hexawing 关闭了讨论。 04月28日 18:22
hexawing 重新开启了讨论。 04月28日 18:22
需要 登录 后方可回复, 如果你还没有账号请 注册新账号