客户端将文件上传到远程服务器的最佳方式?
Best way to upload files by client to remote server?
我有两台服务器。
第一个(Main)是安装了脚本和数据库的服务器。
第二个(远程)是仅上传文件(仅用于存储)的服务器。
现在我对如何上传文件感到困惑,我有两个想法可以做到这一点,但我不知道它们是否是最好的方法。
思路:
先通过ajax上传文件到主服务器并进行所有安全
操作(检查大小、类型等),然后上传
再次到第二个服务器(远程服务器)。
直接通过ajax上传文件到第二台(远程服务器),
并在那里进行所有检查和安全操作,然后将文件信息发送到第一台服务器(主)以将文件信息存储到数据库中(不推荐)。
我想知道大型上传网站如何存储用户上传的文件,他们如何将文件上传到远程服务器?
两种机制都有效。事实上,我们在我们的两种产品中都尝试过这两种方法。他们每个人都有自己的优点和缺点。
假设:主服务器服务于 Web UI。
让两个服务器分别命名为 main.com
和 remote.com
.
您需要考虑的主要因素有:
跨源资源共享(CORS):检查这是否是一个大问题的最直接的方法是您是否需要支持 IE <= 9。旧版 IE 不支持 XHR2,因此 AJAX 无法上传文件。有流行的回退(例如 iframe 传输),但每个都有自己的问题。
带宽:如果文件先上传到main.com
,再上传到remote.com
,则所需带宽加倍。根据您的服务器是否位于负载均衡器之后,要求会有所不同。直接上传到 remote.com
可以有效地使用带宽。
API响应时间: 除非你的API是做optimistic update,否则需要等到文件完全重新上传到 remote.com
才能可靠地响应。此外,这取决于 main.com
和 remote.com
之间的 RTT。
API 域的数量:这是一个小问题。 Web 客户端必须指定将哪个域用于哪个 API。但是它确实与上面的 CORS 问题有关。
性能:如果网络服务器正在处理文件上传,当服务器处理大文件(或大量文件)时可能会出现性能问题.它可能会影响其他用户。
机制
1.客户端上传到 main.com
。 main.com
重新上传到 remote.com
- CORS:没问题
- 带宽:双倍
- 响应时间:双倍(往返);正常(乐观)
- API 域:一个
- 性能:可能会影响网络服务
2。客户端上传到 remote.com
。 remote.com
发送信息给 main.com
- CORS:有问题
- 带宽:高效
- 响应时间:高效
- API 域:两个
- 性能:没有问题
3。 [额外] 客户端上传到 main.com
。 main.com
将文件流式传输到 remote.com
。 remote.com
发回文件信息。
- CORS:没问题
- 带宽:双倍
- 响应时间:不到两倍(流)
- API 域:一个
- 性能:比方法 1 更好的内存占用
结论
根据您的用例,您需要使用不同的机制。对于我们的案例,我们对遗留产品使用方法 2(直接上传),因为我们需要支持遗留浏览器(IE 7、FF 3)。跨域问题一直困扰着我们许多不同的情况(例如,当客户在代理后面时,等等)。
我们对新产品使用方法 1。带宽和响应时间问题在正常情况下还可以,但是当web服务器和远程服务器跨大陆部署时,性能就很差了。我们做了很多优化使其可以接受,但它仍然比方法2差。
方法三是我自己在一个业余项目中使用的。它被包含在这里是因为我认为它也是一个很好的候选者。
编辑
流式传输(方法三)和重新上传(方法一)的区别主要在于文件在main.com
中的存储方式。这会影响资源分配。
为了重新上传,上传的2GB文件首先存储在main.com
,然后重新上传到remote.com
。 main.com
不得不分配资源来临时存放文件(磁盘space,内存,CPU用于IO)。此外,作为一个串行过程,完成上传到 remote.com
所需的总时间加倍(假设上传到 main.com
的时间等于上传到 remote.com
的时间)。
对于流式传输,上传到 main.com
的文件会同时上传到 remote.com
。由于 main.com
在收到文件块后立即将文件块上传到 remote.com
,因此上传过程重叠,从而缩短了上传时间(不到两倍)。换句话说,如果 main.com
不需要处理,main.com
实际上是 remote.com
的代理。此外,由于文件没有作为一个整体存储在 main.com
上(块通常存储在内存中),因此它不会比重新上传消耗那么多资源。但是,如果main.com
需要将文件作为一个整体来处理,那么流式处理并没有带来太大的好处。
我有两台服务器。
第一个(Main)是安装了脚本和数据库的服务器。
第二个(远程)是仅上传文件(仅用于存储)的服务器。
现在我对如何上传文件感到困惑,我有两个想法可以做到这一点,但我不知道它们是否是最好的方法。
思路:
先通过ajax上传文件到主服务器并进行所有安全 操作(检查大小、类型等),然后上传 再次到第二个服务器(远程服务器)。
直接通过ajax上传文件到第二台(远程服务器), 并在那里进行所有检查和安全操作,然后将文件信息发送到第一台服务器(主)以将文件信息存储到数据库中(不推荐)。
我想知道大型上传网站如何存储用户上传的文件,他们如何将文件上传到远程服务器?
两种机制都有效。事实上,我们在我们的两种产品中都尝试过这两种方法。他们每个人都有自己的优点和缺点。
假设:主服务器服务于 Web UI。
让两个服务器分别命名为 main.com
和 remote.com
.
您需要考虑的主要因素有:
跨源资源共享(CORS):检查这是否是一个大问题的最直接的方法是您是否需要支持 IE <= 9。旧版 IE 不支持 XHR2,因此 AJAX 无法上传文件。有流行的回退(例如 iframe 传输),但每个都有自己的问题。
带宽:如果文件先上传到
main.com
,再上传到remote.com
,则所需带宽加倍。根据您的服务器是否位于负载均衡器之后,要求会有所不同。直接上传到remote.com
可以有效地使用带宽。API响应时间: 除非你的API是做optimistic update,否则需要等到文件完全重新上传到
remote.com
才能可靠地响应。此外,这取决于main.com
和remote.com
之间的 RTT。API 域的数量:这是一个小问题。 Web 客户端必须指定将哪个域用于哪个 API。但是它确实与上面的 CORS 问题有关。
性能:如果网络服务器正在处理文件上传,当服务器处理大文件(或大量文件)时可能会出现性能问题.它可能会影响其他用户。
机制
1.客户端上传到 main.com
。 main.com
重新上传到 remote.com
- CORS:没问题
- 带宽:双倍
- 响应时间:双倍(往返);正常(乐观)
- API 域:一个
- 性能:可能会影响网络服务
2。客户端上传到 remote.com
。 remote.com
发送信息给 main.com
- CORS:有问题
- 带宽:高效
- 响应时间:高效
- API 域:两个
- 性能:没有问题
3。 [额外] 客户端上传到 main.com
。 main.com
将文件流式传输到 remote.com
。 remote.com
发回文件信息。
- CORS:没问题
- 带宽:双倍
- 响应时间:不到两倍(流)
- API 域:一个
- 性能:比方法 1 更好的内存占用
结论
根据您的用例,您需要使用不同的机制。对于我们的案例,我们对遗留产品使用方法 2(直接上传),因为我们需要支持遗留浏览器(IE 7、FF 3)。跨域问题一直困扰着我们许多不同的情况(例如,当客户在代理后面时,等等)。
我们对新产品使用方法 1。带宽和响应时间问题在正常情况下还可以,但是当web服务器和远程服务器跨大陆部署时,性能就很差了。我们做了很多优化使其可以接受,但它仍然比方法2差。
方法三是我自己在一个业余项目中使用的。它被包含在这里是因为我认为它也是一个很好的候选者。
编辑
流式传输(方法三)和重新上传(方法一)的区别主要在于文件在main.com
中的存储方式。这会影响资源分配。
为了重新上传,上传的2GB文件首先存储在main.com
,然后重新上传到remote.com
。 main.com
不得不分配资源来临时存放文件(磁盘space,内存,CPU用于IO)。此外,作为一个串行过程,完成上传到 remote.com
所需的总时间加倍(假设上传到 main.com
的时间等于上传到 remote.com
的时间)。
对于流式传输,上传到 main.com
的文件会同时上传到 remote.com
。由于 main.com
在收到文件块后立即将文件块上传到 remote.com
,因此上传过程重叠,从而缩短了上传时间(不到两倍)。换句话说,如果 main.com
不需要处理,main.com
实际上是 remote.com
的代理。此外,由于文件没有作为一个整体存储在 main.com
上(块通常存储在内存中),因此它不会比重新上传消耗那么多资源。但是,如果main.com
需要将文件作为一个整体来处理,那么流式处理并没有带来太大的好处。