直接从客户端提交到云服务哪里,不要经过应用服务器
http://docs.upyun.com/api/form_api/
如果你可以使用 Rails 5.2 的话,可以尝试用 Active Storage,我实现的 activestorage-aliyun 已经支持直接从客户端上传文件到阿里云 OSS 了。
详见 http://edgeguides.rubyonrails.org/active_storage_overview.html#direct-uploads
然后 Carrierwave 也有 direct upload
的插件 https://github.com/dwilkie/carrierwave_direct
直传稍微有点不好的就是没办法做大小限制,再就是有时候云服务商回调的时候有存在回调失败的情况,之后就很难处理这种回调失败的数据
如果单传图片,或者不需要处理的文件,则直连非常好使
如果 server 不是阿里云呢,我们的 server 是台物理机,并且我们也切不到 Rails5...并且上传完文件我们的应用层还需要进行转换操作,需要对上传的文件进行处理,如果彻底绕开应用层开发的时间就会拉长了。。。我在想是不是能够有别的方法在应用层实现上传并发...
用 rails 来处理 4000 并发的上传,单机基本不可能。
rails 限制不能使用异步方式,所以只能用线程. 按照一个 puma 进程配置 100 个线程,至少要 40 个 puma 进程。
所以上传这一块,只能用其它的高并发语言来写。或用 ruby ,但只需要 em 之类的异步方式,与 rails 的数据交互走 redis ,或上传成功后再调用 rails 接口。
另外一种简单的做法,使用 nginx upload module, nginx 是异步模型,所以不用担心性能问题. https://www.nginx.com/resources/wiki/modules/upload/
不过,4000 用户同时上传,按 100Mbps 带宽来算,一个人的上传带宽只有 25 Kbps . 300 Mbyte 的文件. (300 * 1024 * 8) / 25.6 / (60 * 60) 一个人上传 300M 差不多要 26 小时才能上传完。改成 1000 M 带宽,也要 2.6 小时. 千 M 带宽的成本真不低吧。
你不可能靠里面自己的物理服务器来做这件事的。
最大的问题是你们的服务器带宽,例如 Ruby China 只有 5M。
5M 的概念等于同一时刻最大传输只能 5M。
上面思路都已经有了,核心就是这个量的上传文件,文件不应该经过应用服务器(不管是 Puma 还是 Nginx),否则你的应用服务器的正常功能会受到这写文件上传影响。
当然,Nginx 这样的异步 IO 没问题,但 Ruby 的应用服务器是同步 IO 的,意味着上传过程会堵塞,直到上传结束。
如果你们确实无法使用云存储服务,必须用自己的物理机来存储这些上传文件,那你可以考虑把上传服务独立部署,和应用服务器分开。
前提是服务器带宽(用户端 -> 你们的上传服务器)得够大。那种 5M 的带宽的云服务器你就别想搞了。